3160 最长公共子串
题目描述 Description
给出两个由小写字母组成的字符串,求它们的最长公共子串的长度。
输入描述 Input Description
读入两个字符串
输出描述 Output Description
输出最长公共子串的长度
样例输入 Sample Input
yeshowmuchiloveyoumydearmotherreallyicannotbelieveit
yeaphowmuchiloveyoumydearmother
样例输出 Sample Output
27
数据范围及提示 Data Size & Hint
单个字符串的长度不超过1000000
后缀自动机,把第一个串建立后缀自动机,第二个匹配。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<set> 6 #include<ctime> 7 #include<vector> 8 #include<queue> 9 #include<algorithm> 10 #include<map> 11 #include<cmath> 12 #define eps 1e-6 13 #define inf 1000000000 14 #define mod 1000000007 15 #define pa pair<int,int> 16 #define ll long long 17 using namespace std; 18 ll read() 19 { 20 ll x=0;char ch=getchar(); 21 while(ch<'0'||ch>'9')ch=getchar(); 22 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 23 return x; 24 } 25 int ans; 26 char ch[100005]; 27 struct sam{ 28 int p,q,np,nq; 29 int cnt,last; 30 int a[200005][26],l[200005],fa[200005]; 31 sam(){ 32 last=++cnt; 33 } 34 void extend(int c){ 35 p=last;np=last=++cnt;l[np]=l[p]+1; 36 while(!a[p][c]&&p)a[p][c]=np,p=fa[p]; 37 if(!p)fa[np]=1; 38 else 39 { 40 q=a[p][c]; 41 if(l[p]+1==l[q])fa[np]=q; 42 else 43 { 44 nq=++cnt;l[nq]=l[p]+1; 45 memcpy(a[nq],a[q],sizeof(a[q])); 46 fa[nq]=fa[q]; 47 fa[np]=fa[q]=nq; 48 while(a[p][c]==q)a[p][c]=nq,p=fa[p]; 49 } 50 } 51 } 52 void build(){ 53 scanf("%s",ch+1); 54 int len=strlen(ch+1); 55 for(int i=1;i<=len;i++) 56 extend(ch[i]-'a'); 57 } 58 void solve(){ 59 scanf("%s",ch+1); 60 int len=strlen(ch+1),now=1,tmp=0; 61 for(int i=1;i<=len;i++) 62 { 63 int c=ch[i]-'a'; 64 if(a[p][c])p=a[p][c],tmp++; 65 else 66 { 67 while(p&&!a[p][c])p=fa[p]; 68 if(!p)p=1,tmp=0; 69 else tmp=l[p]+1,p=a[p][c]; 70 } 71 ans=max(ans,tmp); 72 } 73 printf("%d\n",ans); 74 } 75 }sam; 76 int main() 77 { 78 sam.build(); 79 sam.solve(); 80 return 0; 81 }