HUSTOJ 2796 && SPOJ1811

传送门:http://begin.lydsy.com/JudgeOnline/problem.php?id=2796

题解:后缀自动机,很裸,但是感觉对后缀自动机还不是特别理解,毕竟我太蒟蒻,等我精通了,再写对它的理解吧。。。

   还有写这道题的时候发现数组下标又时候是负数竟然不会爆。。。。。。因为这道题有大写也有小写,可我只开了26竟然A了(后面才发现)。。。。懒得改了

代码:

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #define N 250005
 6 using namespace std;
 7 struct data{
 8     int go[26],val,fa;
 9 }son[N*2];
10 int n,m,tot,last,root,sum,ans;
11 char s[N],c[N];
12 int newnode(int x){son[++tot].val=son[x].val+1; return tot;}
13 void extend(int x)
14 {
15     int p=last,np=newnode(p);
16     while (p && !son[p].go[x]) son[p].go[x]=np,p=son[p].fa;
17     if (!p) son[np].fa=root;
18     else
19     {
20         int q=son[p].go[x];
21         if (son[q].val==son[p].val+1) son[np].fa=q;
22         else
23         {
24             int nq=newnode(p);
25             memcpy(son[nq].go,son[q].go,sizeof(son[q].go));
26             son[nq].fa=son[q].fa;
27             son[q].fa=son[np].fa=nq;
28             while (p && son[p].go[x]==q) son[p].go[x]=nq,p=son[p].fa;
29         }
30     }
31     last=np;
32 }
33 int main()
34 {
35     last=root=tot=1; 
36     scanf("%s",s+1); scanf("%s",c+1);
37     n=strlen(s+1); m=strlen(c+1);
38     for (int i=1; i<=n; i++) extend(s[i]-'a');
39     for(int i=1,pp=root;i<=m;i++){
40         int f=c[i]-'a';
41         if(son[pp].go[f]) sum++,pp=son[pp].go[f];
42         else{
43             while(pp && !son[pp].go[f]) pp=son[pp].fa;
44             if(pp) sum=son[pp].val+1,pp=son[pp].go[f];
45             else sum=0,pp=root;
46         }
47         ans=max(ans,sum);
48     }
49     printf("%d\n",ans);
50 }
View Code

 

posted @ 2016-05-31 19:50  ACist  阅读(324)  评论(0编辑  收藏  举报