bzoj 4566: [Haoi2016]找相同字符
一直忘了放模板。。。
把两个串连起来做个后缀自动机对每个字串统计答案就行了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define N 800005 6 using namespace std; 7 int read() 8 { 9 int p=0;char c=getchar(); 10 while(c<'0'||c>'9')c=getchar(); 11 while(c>='0'&&c<='9')p=p*10+c-'0',c=getchar(); 12 return p; 13 } 14 int n,m; 15 char s[N],ss[200004],sss[200004]; 16 int l[N],tot,fa[N],ch[N][30],v1[N],v2[N]; 17 long long ans; 18 int qq[N]; 19 bool cmp(int x,int y) 20 { 21 return l[x]>l[y]; 22 } 23 void build() 24 { 25 int lst=0; 26 for(int i=0;i<=n+m;i++) 27 { 28 int c=s[i]-'a'; 29 int p=lst;int np=++tot;lst=np; 30 l[np]=l[p]+1; 31 if(i<n)v1[np]=1; 32 if(i>n)v2[np]=1; 33 while(p&&!ch[p][c])ch[p][c]=np,p=fa[p]; 34 int q=ch[p][c]; 35 if(!q) 36 { 37 ch[p][c]=np; 38 continue; 39 } 40 else if(l[q]==l[p]+1) 41 { 42 fa[np]=q; 43 continue; 44 } 45 tot++;fa[tot]=fa[q]; 46 fa[q]=fa[np]=tot; 47 l[tot]=l[p]+1; 48 for(int j=0;j<27;j++)ch[tot][j]=ch[q][j]; 49 while(p&&ch[p][c]==q)ch[p][c]=tot,p=fa[p]; 50 if(ch[p][c]==q)ch[p][c]=tot; 51 } 52 for(int i=0;i<=tot;i++)qq[i]=i; 53 sort(qq,qq+tot+1,cmp); 54 for(int i=0;i<=tot;i++) 55 { 56 v1[fa[qq[i]]]+=v1[qq[i]]; 57 v2[fa[qq[i]]]+=v2[qq[i]]; 58 } 59 for(int i=0;i<=tot;i++) 60 { 61 ans+=(long long)(l[i]-l[fa[i]])*v1[i]*v2[i]; 62 } 63 return ; 64 } 65 int main() 66 { 67 scanf("%s",ss); 68 scanf("%s",sss); 69 n=strlen(ss);m=strlen(sss); 70 for(int i=0;i<n;i++)s[i]=ss[i]; 71 s[n]='z'+1; 72 for(int i=0;i<m;i++)s[i+n+1]=sss[i]; 73 build(); 74 printf("%lld\n",ans); 75 return 0; 76 } 77 /* 78 babb 79 abbb 80 */