标签:read scan set tchar esc man log getch 自动机
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
#include <iostream> #include <cstdio> #include <string> #include <cstring> inline long long read(){long long x=0,f=1;char ch=getchar();while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}return x*f;} using namespace std; const long long INF = 1e14; const int N = 5e5+7; const long long mod = 1000000007; struct SAM{ int isPlus[N * 2],endpos[N * 2];int d[N * 2]; int cnt[N * 2];int pos[N]; int tot,slink[2*N],trans[2*N][28],minlen[2*N],maxlen[2*N],pre; int newstate(int _maxlen,int _minlen,int* _trans,int _slink){ maxlen[++tot]=_maxlen;minlen[tot]=_minlen; slink[tot]=_slink; if(_trans)for(int i=0;i<26;i++)trans[tot][i]=_trans[i]; return tot; } int add_char(char ch,int u){ int c=ch-‘a‘,v=u; int z=newstate(maxlen[u]+1,-1,NULL,0); isPlus[z] = 1; while(v&&!trans[v][c]){trans[v][c]=z;d[z]+=1;v=slink[v];} if(!v){ minlen[z]=1;slink[z]=1;return z;} int x=trans[v][c]; if(maxlen[v]+1==maxlen[x]){slink[z]=x;minlen[z]=maxlen[x]+1;return z;} int y=newstate(maxlen[v]+1,-1,trans[x],slink[x]); slink[z]=slink[x]=y;minlen[x]=minlen[z]=maxlen[y]+1; while(v&&trans[v][c]==x){trans[v][c]=y;d[x]--,d[y]++;v=slink[v];} minlen[y]=maxlen[slink[y]]+1; return z; } void init_sam() { for(int i = 1; i <= tot; ++i) for(int j = 0; j < 26; ++j) trans[i][j] = 0; pre = tot = 1; } }A,B; unsigned long long f[N],dp[N]; char a[N],b[N]; int main() { int T,cas = 1; scanf("%d",&T); while(T--) { scanf("%s%s",a,b); int n = strlen(a); int m = strlen(b); A.init_sam(); B.init_sam(); for(int i = 0; i < n; ++i) A.pre = A.add_char(a[i],A.pre); for(int i = 0; i < m; ++i) B.pre = B.add_char(b[i],B.pre); for(int i = 0; i <= m; ++i) B.cnt[i] = 0; for(int i = 1; i <= B.tot; ++i) B.cnt[B.maxlen[i]] += 1; for(int i = 1; i <= m; ++i) B.cnt[i] += B.cnt[i-1]; for(int i = B.tot; i >= 1; --i) B.pos[B.cnt[B.maxlen[i]]--] = i; for(int i = 0; i <= n; ++i) A.cnt[i] = 0; for(int i = 1; i <= A.tot; ++i) A.cnt[A.maxlen[i]] += 1; for(int i = 1; i <= n; ++i) A.cnt[i] += A.cnt[i-1]; for(int i = A.tot; i >= 1; --i) A.pos[A.cnt[A.maxlen[i]]--] = i; memset(f,0,sizeof(f)); memset(dp,0,sizeof(dp)); for(int i = B.tot; i >= 1; --i) { int v = B.pos[i]; f[v] = 1; for(int j = 0; j < 26; ++j) { if(B.trans[v][j])f[v] += f[B.trans[v][j]]; } } for(int i = 0; i < 26; ++i) dp[i] = f[B.trans[1][i]]; unsigned long long ans = 0; for(int i = A.tot; i >= 1; --i) { int v = A.pos[i]; for(int j = 0; j < 26; ++j) { if(A.trans[v][j] == 0) { ans += dp[j]*(A.maxlen[v] - A.minlen[v] + 1); } } } for(int i = A.tot; i >= 2; --i) ans += (A.maxlen[i] - A.minlen[i] + 1); cout<<ans+1<<endl; } return 0; }
HDU 5343 MZL's Circle Zhou 后缀自动机+DP
标签:read scan set tchar esc man log getch 自动机
原文地址:http://www.cnblogs.com/zxhl/p/7620482.html