题目链接:http://begin.lydsy.com/JudgeOnline/problem.php?id=2796
把一个字符串做出后缀自动机,另一个字符串与之匹配。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #define inf 1<<30 5 #define maxn 250005 6 using namespace std; 7 int tot,last,root,ans,sum,n,m; 8 char s[maxn],c[maxn]; 9 struct fuck{int par,go[26],val;}suf[maxn*2]; 10 int newnode(int x){suf[++tot].val=suf[x].val+1;return tot;} 11 void extend(int x){ 12 int p=last,np=newnode(p); 13 while(p&&suf[p].go[x]==0) suf[p].go[x]=np,p=suf[p].par; 14 if(p==0) suf[np].par=root; 15 else{ 16 int q=suf[p].go[x]; 17 if(suf[q].val==suf[p].val+1) suf[np].par=q; 18 else{ 19 int nq=newnode(p); 20 memcpy(suf[nq].go,suf[q].go,sizeof(suf[q].go)); 21 suf[nq].par=suf[q].par; 22 suf[q].par=suf[np].par=nq; 23 while(p&&suf[p].go[x]==q) suf[p].go[x]=nq,p=suf[p].par; 24 } 25 } 26 last=np; 27 } 28 int main(){ 29 last=root=tot=1; ans=0; 30 scanf("%s%s",s,c); 31 n=strlen(s),m=strlen(c); 32 for(int i=0;i<n;i++) extend(s[i]-'a'); 33 for(int i=0,pp=root;i<m;i++){ 34 int f=c[i]-'a'; 35 if(suf[pp].go[f]) sum++,pp=suf[pp].go[f]; 36 else{ 37 while(pp && !suf[pp].go[f]) pp=suf[pp].par; 38 if(pp) sum=suf[pp].val+1,pp=suf[pp].go[f]; 39 else sum=0,pp=root; 40 } 41 ans=max(ans,sum); 42 } 43 printf("%d ",ans); 44 return 0; 45 }