CodeVS3160 最长公共子串
题目描述 Description
给出两个由小写字母组成的字符串,求它们的最长公共子串的长度。
输入描述 Input Description
读入两个字符串
输出描述 Output Description
输出最长公共子串的长度
样例输入 Sample Input
yeshowmuchiloveyoumydearmotherreallyicannotbelieveit
yeaphowmuchiloveyoumydearmother
样例输出 Sample Output
27
数据范围及提示 Data Size & Hint
单个字符串的长度不超过100000
和POJ2774没有半点区别
用来练习后缀自动机模板……
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 const int mxn=200100; 9 int read(){ 10 int x=0,f=1;char ch=getchar(); 11 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 char s[mxn]; 16 struct SAM{ 17 int t[mxn][27]; 18 int fa[mxn]; 19 int l[mxn]; 20 int last,S,cnt; 21 void init(){S=last=cnt=1;return;} 22 void add(int c){ 23 int p=last,np=++cnt; 24 last=np; 25 l[np]=l[p]+1; 26 for(;p && !t[p][c];p=fa[p])t[p][c]=np; 27 if(!p)fa[np]=S; 28 else{ 29 int q=t[p][c]; 30 if(l[p]+1==l[q])fa[np]=q; 31 else{ 32 int nq=++cnt; 33 l[nq]=l[p]+1; 34 memcpy(t[nq],t[q],sizeof t[q]); 35 fa[nq]=fa[q]; 36 fa[np]=fa[q]=nq; 37 for(;t[p][c]==q;p=fa[p])t[p][c]=nq; 38 } 39 } 40 } 41 void solve(){ 42 scanf("%s",s+1); 43 int len=strlen(s+1); 44 int now=S,tmp=0; 45 int ans=0; 46 for(int i=1;i<=len;i++){ 47 int c=s[i]-'a'; 48 if(t[now][c])now=t[now][c],tmp++; 49 else{ 50 while(now && !t[now][c])now=fa[now]; 51 if(!now)now=S,tmp=0; 52 else{ 53 tmp=l[now]+1;//当前串长 54 now=t[now][c]; 55 } 56 } 57 ans=max(ans,tmp); 58 } 59 printf("%d\n",ans); 60 return; 61 } 62 }sa; 63 int main(){ 64 int i,j; 65 scanf("%s",s+1); 66 int len=strlen(s+1); 67 sa.init(); 68 for(i=1;i<=len;i++) 69 sa.add(s[i]-'a'); 70 sa.solve(); 71 return 0; 72 }
本文为博主原创文章,转载请注明出处。