码迷,mamicode.com
首页 > 其他好文 > 详细

后缀自动机

时间:2015-04-07 00:41:57      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

理解起来好困难啊QAQ

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

见CLJppt

技术分享
 1 char s[maxn];
 2 struct sam
 3 {
 4     int n,last,cnt;
 5     int go[maxn][26],l[maxn],fa[maxn];
 6     void add(int x)
 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);
29         for0(i,m-1)add(s[i]-a);
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

正解是SAM+LCT,但出题人显然没有卡暴力。。。写了个暴力结果跑了rank4 233

犯了一个sb错就是没有更新lastQAQ

技术分享
 1 char s[2*maxn];
 2 int mask;
 3 struct sam
 4 {
 5     int last,cnt,fa[maxn],go[maxn][26],l[maxn],r[maxn];
 6     sam(){last=cnt=1;}
 7     void add(int x)
 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     {
30         int n=strlen(s),t=mask;
31         for0(i,n-1){mask=(mask*131+i)%n;swap(s[i],s[mask]);}
32         mask=t;
33         for0(i,n-1)add(s[i]-A);
34     }
35     void query(char s[])
36     {
37         int n=strlen(s),now=1,t=mask;
38         for0(i,n-1){mask=(mask*131+i)%n;swap(s[i],s[mask]);}
39         for0(i,n-1)now=go[now][s[i]-A];
40         mask=t^r[now];
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);
48     int Q=read();
49     scanf("%s",s);int n=strlen(s);for0(i,n-1)T.add(s[i]-A);
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

 

后缀自动机

标签:

原文地址:http://www.cnblogs.com/zyfzyf/p/4397216.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!