1. 程式人生 > >UVALive - 7041 The Problem to Slow Down You (回文樹)

UVALive - 7041 The Problem to Slow Down You (回文樹)

ifdef sign space blank eps for str ini pri

https://vjudge.net/problem/UVALive-7041

題意

給出兩個僅包含小寫字符的字符串 A 和 B ;
求:對於 A 中的每個回文子串,B 中和該子串相同的子串個數的總和。

分析

從0和1兩個根節點DFS下去,如果兩個相同的節點同時存在就統計答案。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include 
<cmath> #include <ctime> #include <vector> #include <queue> #include <map> #include <stack> #include <set> #include <bitset> using namespace std; typedef long long ll; typedef unsigned long long ull; #define ms(a, b) memset(a, b, sizeof(a)) #define
pb push_back #define mp make_pair #define pii pair<int, int> //#define eps 0.0000000001 #define IOS ios::sync_with_stdio(0);cin.tie(0); #define random(a, b) rand()*rand()%(b-a+1)+a #define pi acos(-1) //const ll INF = 0x3f3f3f3f3f3f3f3fll; const int inf = 0x3f3f3f3f; const int maxn = 2e5 + 10; const int
maxm = 3000000 +10; const int mod = 1000000007; struct PAM{ int nxt[maxn][26]; int fail[maxn]; int cnt[maxn]; int num[maxn]; int len[maxn]; int s[maxn]; int last,n,p; int newnode(int w){ for(int i=0;i<26;i++) nxt[p][i]=0; num[p]=cnt[p]=0; len[p]=w; return p++; } void init(){ n=last=p=0; newnode(0); newnode(-1); s[n]=-1; fail[0]=1; } int get_fail(int x){ while(s[n-len[x]-1]!=s[n]) x=fail[x]; return x; } void add(int c){ c-=a; s[++n]=c; int cur=get_fail(last); if(!nxt[cur][c]){ int now=newnode(len[cur]+2); fail[now]=nxt[get_fail(fail[cur])][c]; nxt[cur][c]=now; num[now]=num[fail[now]]+1; } last=nxt[cur][c]; cnt[last]++; } void Count(){ for(int i=p-1;i>=0;i--) cnt[fail[i]]+=cnt[i]; } }; PAM pam1,pam2; char a[maxn],b[maxn]; ll dfs(int an,int bn){ ll res=0; for(int i=0;i<26;i++) if(pam1.nxt[an][i]!=0&&pam2.nxt[bn][i]!=0){ res+=(ll)pam1.cnt[pam1.nxt[an][i]]*pam2.cnt[pam2.nxt[bn][i]]+dfs(pam1.nxt[an][i],pam2.nxt[bn][i]); } return res; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("input.txt", "w", stdout); #endif int T,cas=1; scanf("%d",&T); while(T--){ pam1.init(); pam2.init(); scanf("%s%s",a,b); int l1=strlen(a),l2=strlen(b); for(int i=0;i<l1;i++) pam1.add(a[i]); for(int i=0;i<l2;i++) pam2.add(b[i]); pam1.Count(); pam2.Count(); ll ans=dfs(0,0)+dfs(1,1); printf("Case #%d: %lld\n",cas++,ans); } return 0; }

UVALive - 7041 The Problem to Slow Down You (回文樹)