# 后缀自动机

WIKIOI3160 求两个串的最长公共子串

 1 char s[maxn];
2 struct sam
3 {
4     int n,last,cnt;
5     int go[maxn][26],l[maxn],fa[maxn];
7     {
8         int p=last,np=last=++cnt;l[np]=l[p]+1;
9         for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
10         if(!p)fa[np]=1;
11         else
12         {
13             int q=go[p][x];
14             if(l[p]+1==l[q])fa[np]=q;
15             else
16             {
17                 int nq=++cnt;l[nq]=l[p]+1;
18                 memcpy(go[nq],go[q],sizeof(go[q]));
19                 fa[nq]=fa[q];
20                 fa[np]=fa[q]=nq;
21                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
22             }
23         }
24     }
25     void init()
26     {
27         last=cnt=1;
28         scanf("%s",s);int m=strlen(s);
30     }
31     void solve()
32     {
33         scanf("%s",s);int m=strlen(s),now=1,t=0,ans=0;
34         for0(i,m-1)
35         {
36             int x=s[i]-'a';
37             if(go[now][x])t++,now=go[now][x];
38             else
39             {
40                 while(now&&!go[now][x])now=fa[now];
41                 if(!now)t=0,now=1;
42                 else t=l[now]+1,now=go[now][x];
43             }
44             ans=max(ans,t);
45         }
46         printf("%d\n",ans);
47     }
48 }T;
49 int main()
50 {
51     T.init();
52     T.solve();
53     return 0;
54 }
View Code

BZOJ2555: SubString

 1 char s[2*maxn];
3 struct sam
4 {
5     int last,cnt,fa[maxn],go[maxn][26],l[maxn],r[maxn];
6     sam(){last=cnt=1;}
8     {
9         int p=last,np=++cnt;last=np;l[np]=l[p]+1;
10         for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
11         if(!p)fa[np]=1;
12         else
13         {
14             int q=go[p][x];
15             if(l[p]+1==l[q])fa[np]=q;
16             else
17             {
18                 int nq=++cnt;l[nq]=l[p]+1;
19                 memcpy(go[nq],go[q],sizeof(go[q]));
20                 r[nq]=r[q];
21                 fa[nq]=fa[q];
22                 fa[q]=fa[np]=nq;
23                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
24             }
25         }
26         for(;np;np=fa[np])r[np]++;
27     }
28     void insert(char s[])
29     {
34     }
35     void query(char s[])
36     {
39         for0(i,n-1)now=go[now][s[i]-'A'];
41         printf("%d\n",r[now]);
42     }
43 }T;
44 int main()
45 {
46     freopen("input.txt","r",stdin);
47     freopen("output.txt","w",stdout);
50     while(Q--)
51     {
52         scanf("%s",s);
53         if(s[0]=='A'){scanf("%s",s);T.insert(s);}
54         else {scanf("%s",s);T.query(s);}
55     }
56     return 0;
57 }
View Code

BZOJ3238: [Ahoi2013]差异

 1 struct sam
2 {
4     char ch[maxn];
5     struct edge{int go,next;}e[maxn];
7     {
8         int p=last,np=last=++cnt;l[np]=l[p]+1;
9         for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
10         if(!p)fa[np]=1;
11         else
12         {
13             int q=go[p][x];
14             if(l[p]+1==l[q])fa[np]=q;
15             else
16             {
17                 int nq=++cnt;l[nq]=l[p]+1;
18                 memcpy(go[nq],go[q],sizeof(go[q]));
19                 fa[nq]=fa[q];
20                 fa[q]=fa[np]=nq;
21                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
22             }
23         }
24         s[np]=1;
25     }
26     void init()
27     {
28         last=cnt=1;
29         scanf("%s",ch);int n=strlen(ch);ans=(ll)(n-1)*n*(n+1)/2;
31     }
33     {
35     }
36     void dfs(int x)
37     {
38         for4(i,x)
39         {
40             dfs(y);
41             ans-=(ll)2*s[y]*s[x]*l[x];
42             s[x]+=s[y];
43         }
44     }
45     void work()
46     {
48         dfs(1);
49         cout<<ans<<endl;
50     }
51 }T;
52 int main()
53 {
54     freopen("input.txt","r",stdin);
55     freopen("output.txt","w",stdout);
56     T.init();
57     T.work();
58     return 0;
59 }
View Code

BZOJ2946: [Poi2000]公共串

 1 int n;
2 struct sam
3 {
4     int last,cnt,l[maxn],fa[maxn],go[maxn][26],mx[maxn][5];
5     char s[maxn];
7     {
8         int p=last,np=last=++cnt;l[np]=l[p]+1;
9         for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
10         if(!p)fa[np]=1;
11         else
12         {
13             int q=go[p][x];
14             if(l[p]+1==l[q])fa[np]=q;
15             else
16             {
17                 int nq=++cnt;l[nq]=l[p]+1;
18                 memcpy(go[nq],go[q],sizeof(go[q]));
19                 fa[nq]=fa[q];
20                 fa[q]=fa[np]=nq;
21                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
22             }
23         }
24     }
25     void insert()
26     {
27         last=cnt=1;
28         scanf("%s",s);int n=strlen(s);
30     }
31     void work(int k)
32     {
33         scanf("%s",s);int n=strlen(s),now=1,t=0;
34         for0(i,n-1)
35         {
36             int x=s[i]-'a';
37             if(go[now][x]){t++;now=go[now][x];}
38             else
39             {
40                 while(now&&!go[now][x])now=fa[now];
41                 if(!now){t=0;now=1;}
42                 else t=l[now]+1,now=go[now][x];
43             }
44             for(int j=now;j;j=fa[j])mx[j][k]=max(mx[j][k],t);
45         }
46     }
47     void print()
48     {
49         int ans=0;
50         for1(i,cnt)
51         {
52             int t=l[i];
53             for0(j,n-1)t=min(t,mx[i][j]);
54             ans=max(ans,t);
55         }
56         cout<<ans<<endl;
57     }
58 }T;
59 int main()
60 {
61     freopen("input.txt","r",stdin);
62     freopen("output.txt","w",stdout);
64     T.insert();
65     for0(i,n-1)T.work(i);
66     T.print();
67     return 0;
68 }
View Code

BZOJ3879: SvT

  1 int n,m,a[maxn],id[maxn],v[maxn],top,sta[maxn],dep[maxn];
2 ll ans;
3 struct sam
4 {
6     struct edge{int go,next;}e[maxn];
7     char s[maxn];
9     {
11     }
13     {
14         int p=last,np=last=++cnt;l[np]=l[p]+1;
15         for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
16         if(!p)fa[np]=1;
17         else
18         {
19             int q=go[p][x];
20             if(l[p]+1==l[q])fa[np]=q;
21             else
22             {
23                 int nq=++cnt;l[nq]=l[p]+1;
24                 memcpy(go[nq],go[q],sizeof(go[q]));
25                 fa[nq]=fa[q];
26                 fa[q]=fa[np]=nq;
27                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
28             }
29         }
30         return np;
31     }
32     int lca(int x,int y)
33     {
34         if(dep[x]<dep[y])swap(x,y);
35         int t=dep[x]-dep[y];
36         for0(i,18)if(t>>i&1)x=f[x][i];
37         if(x==y)return x;
38         for3(i,18,0)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
39         return f[x][0];
40     }
41     void dfs(int x)
42     {
43         dfn[x]=++ti;
44         for1(i,18)if(dep[x]>=1<<i)f[x][i]=f[f[x][i-1]][i-1];else break;
45         for4(i,x)
46         {
47           dep[y]=dep[x]+1;f[y][0]=x;
48           dfs(y);
49         }
50     }
51     void init()
52     {
53         last=cnt=1;
54         scanf("%s",s+1);int n=strlen(s+1);
57         dfs(1);
58     }
59 }T;
60 struct graph
61 {
63     struct edge{int go,next;}e[maxn];
65     {
67     }
68     void dfs(int x)
69     {
70         s[x]=v[x];
71         for4(i,x)
72         {
73             dfs(y);
74             ans+=(ll)s[x]*s[y]*T.l[x];
75             s[x]+=s[y];
76         }
78     }
79 }G;
80 inline bool cmp(int x,int y){return T.dfn[x]<T.dfn[y];}
81 int main()
82 {
83     freopen("input.txt","r",stdin);
84     freopen("output.txt","w",stdout);
86     T.init();
87     while(m--)
88     {
91         sort(a+1,a+k+1,cmp);
92         for1(i,k)v[a[i]]=1;
93         sta[top=1]=1;G.tot=0;
94         for1(i,k)
95         {
96             int x=a[i],f=T.lca(sta[top],x);
97             while(dep[f]<dep[sta[top]])
98             {
99                 if(dep[f]>=dep[sta[top-1]])
100                 {
102                     if(sta[top]!=f)sta[++top]=f;
103                     break;
104                 }
106             }
107             if(sta[top]!=x)sta[++top]=x;
108         }
110         ans=0;
111         G.dfs(1);
112         printf("%I64d\n",ans);
113         for1(i,k)v[a[i]]=0;
114     }
115     return 0;
116 }
View Code

2780: [Spoj]8093 Sevenk Love Oimaster

@SDOI2009HH的项链

  1 struct graph
2 {
4     struct edge{int go,next;}e[maxn];
6     {
8     }
9 }A,B;
10 int s[maxn],n,m,pos[maxn];
11 struct rec{int x,y,id;}a[maxn];
12 struct sam
13 {
14     int cnt,last,l[maxn],id[maxn][2],fa[maxn],ti;
15     map<int,int>go[maxn];
16     char s[maxn];
17     sam(){cnt=1;}
19     {
20         int p=last,q;
21         if(q=go[p][x])
22         {
23             if(l[p]+1==l[q])last=q;
24             else
25             {
26                 int nq=++cnt;l[nq]=l[p]+1;
27                 go[nq]=go[q];
28                 fa[nq]=fa[q];
29                 fa[q]=nq;
30                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
31                 last=nq;
32             }
33         }else
34         {
35             int np=++cnt;l[np]=l[p]+1;
36             for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
37             if(!p)fa[np]=1;
38             else
39             {
40                 q=go[p][x];
41                 if(l[p]+1==l[q])fa[np]=q;
42                 else
43                 {
44                     int nq=++cnt;l[nq]=l[p]+1;
45                     go[nq]=go[q];
46                     fa[nq]=fa[q];
47                     fa[q]=fa[np]=nq;
48                     for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
49                 }
50             }
51             last=np;
52         }
54     }
55     void dfs(int x)
56     {
57         id[x][0]=++ti;pos[ti]=x;
58         for4(A,i,x)dfs(y);
59         id[x][1]=ti;
60     }
61     void insert(int y)
62     {
63         last=1;
64         scanf("%s",s);int n=strlen(s);
66     }
67     void work()
68     {
70         dfs(1);
71     }
72     rec find(int j)
73     {
74         scanf("%s",s);int n=strlen(s),now=1;
75         for0(i,n-1)now=go[now][s[i]];
76         return now?(rec){id[now][0],id[now][1],j}:(rec){2,1,j};
77     }
78 }T;
79 void update(int x,int y)
80 {
81     //printf("%d %d\n",x,y);
82     for(;x<=T.cnt;x+=x&(-x))s[x]+=y;
83 }
84 int sum(int x)
85 {
86     int t=0;
87     for(;x;x-=x&(-x))t+=s[x];
88     //cout<<x<<' '<<t<<endl;
89     return t;
90 }
91 int v[maxn],ans[maxn];
92 inline bool cmp(rec a,rec b){return a.y<b.y;}
93 int main()
94 {
95     freopen("input.txt","r",stdin);
96     freopen("output.txt","w",stdout);
98     for1(i,n)T.insert(i);
99     T.work();
100     for1(i,m)a[i]=T.find(i);
101     sort(a+1,a+m+1,cmp);
102     //for1(i,m)cout<<i<<' '<<a[i].x<<' '<<a[i].y<<' '<<a[i].id<<endl;
103     int now=1;
104     for1(i,T.cnt)
105     {
106         for4(B,j,pos[i])
107          {
108             if(v[y])update(v[y],-1);
109             v[y]=i;
110             update(v[y],1);
111          }
112         //cout<<i<<' '<<a[now].x<<' '<<a[now].y<<' '<<a[now].id<<endl;
113         while(a[now].y==i)ans[a[now].id]=sum(a[now].y)-sum(a[now].x-1),now++;
114     }
115     for1(i,m)printf("%d\n",ans[i]);
116     return 0;
117 }
View Code

3473: 字符串

  1 int n,last,cnt=1,ti,k;
2 typedef int arr[maxn];
3 arr l,fa,s,f,pos,a,v;
4 int go[maxn][26],id[maxn][2];
5 char ch[maxn];
6 struct graph
7 {
9     struct edge{int go,next;}e[maxn];
10     inline void add(int x,int y)
11     {
13     }
14 }A,B,C;
16 {
17     int p=last,q;
18     if(q=go[p][x])
19     {
20         if(l[p]+1==l[q])last=q;
21         else
22         {
23             int nq=++cnt;l[nq]=l[p]+1;
24             memcpy(go[nq],go[q],sizeof(go[q]));
25             fa[nq]=fa[q];
26             fa[q]=nq;
27             for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
28             last=nq;
29         }
30     }else
31     {
32         int np=++cnt;l[np]=l[p]+1;
33         for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
34         if(!p)fa[np]=1;
35         else
36         {
37             q=go[p][x];
38             if(l[p]+1==l[q])fa[np]=q;
39             else
40             {
41                 int nq=++cnt;l[nq]=l[p]+1;
42                 memcpy(go[nq],go[q],sizeof(go[q]));
43                 fa[nq]=fa[q];
44                    fa[q]=fa[np]=nq;
45                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
46             }
47         }
48         last=np;
49     }
50 }
51 inline void dfs(int x)
52 {
53     id[x][0]=++ti;pos[ti]=x;
54     for4(C,i,x)dfs(y);
55     id[x][1]=ti;
56 }
57 inline void dfs2(int x)
58 {
59     for4(C,i,x)f[y]+=f[x],dfs2(y);
60 }
61 inline void update(int x,int y)
62 {
63     for(;x<=cnt;x+=x&(-x))s[x]+=y;
64 }
65 inline int sum(int x)
66 {
67     int t=0;
68     for(;x;x-=x&(-x))t+=s[x];
69     return t;
70 }
71 inline bool cmp(int x,int y){return id[x][1]<id[y][1];}
72 int main()
73 {
74     freopen("input.txt","r",stdin);
75     freopen("output.txt","w",stdout);
77     for1(i,n)
78     {
79         last=1;
80         scanf("%s",ch);int m=strlen(ch);
82     }
84     dfs(1);
85     for1(i,cnt)a[i]=i;
86     sort(a+1,a+cnt+1,cmp);
87     int now=1;
88     for1(i,cnt)
89     {
90         for4(A,j,pos[i])
91         {
92             if(v[y])update(v[y],-1);
93             v[y]=i;
94             update(v[y],1);
95         }
96         while(id[a[now]][1]==i)f[a[now]]=(sum(id[a[now]][1])-sum(id[a[now]][0]-1))>=k?l[a[now]]-l[fa[a[now]]]:0,now++;
97     }
98     dfs2(1);
99     for1(i,n)
100     {
101         ll ans=0;
102         for4(B,j,i)ans+=f[y];
103         printf("%lld",ans);if(i!=n)printf(" ");
104     }
105     return 0;
106 }
View Code

3926: [Zjoi2015]诸神眷顾的幻想乡

[捂脸熊]没想到这题这么简单233 因为叶子很少，所以直接枚举所有的叶子把从他开始dfs顺便建立建立广义自动机，然后求本质不同的字符串的个数。然后就完了。。。

 1 int n,k,tot,cnt,last;
2 typedef int arr[maxn];
4 int go[maxn][12];
5 struct edge{int go,next;}e[maxn];
6 inline void add(int x,int y)
7 {
10 }
12 {
13     int p=last,q;
14     if(q=go[p][x])
15     {
16         if(l[p]+1==l[q])last=q;
17         else
18         {
19             int nq=++cnt;l[nq]=l[p]+1;
20             memcpy(go[nq],go[q],sizeof(go[q]));
21             fa[nq]=fa[q];
22             fa[q]=nq;
23             for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
24             last=nq;
25         }
26     }else
27     {
28         int np=++cnt;l[np]=l[p]+1;
29         for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
30         if(!p)fa[np]=1;
31         else
32         {
33             q=go[p][x];
34             if(l[p]+1==l[q])fa[np]=q;
35             else
36             {
37                 int nq=++cnt;l[nq]=l[p]+1;
38                 memcpy(go[nq],go[q],sizeof(go[q]));
39                 fa[nq]=fa[q];
40                    fa[q]=fa[np]=nq;
41                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
42             }
43         }
44         last=np;
45     }
46 }
47 inline void dfs(int x,int f,int z)
48 {
50     int t=last;
51     for4(i,x)if(y!=f){dfs(y,x,last);last=t;}
52 }
53 int main()
54 {
55     freopen("input.txt","r",stdin);
56     freopen("output.txt","w",stdout);
66 }