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 */

 

posted @ 2017-02-18 23:53  SD_le  阅读(269)  评论(0编辑  收藏  举报
重置按钮