COJ885 LCS???
试题描述
|
输入两个字符串A、B,输出他们的最长连续公共子串长度。
|
输入
|
第一行为一个字符串A。 第二行为一个字符串B。
|
输出
|
输出他们的最长连续公共子串长度。
|
输入示例
|
ababab bababbabb
|
输出示例
|
5
|
其他说明
|
1<=|A|,|B|<=100000 A、B均由小写字母a或b组成。
|
水水哒SAM
将A建立SAM,将B在A上运行,同时维护当前节点的最多匹配长度
#include<cstdio> #include<cctype> #include<queue> #include<cstring> #include<algorithm> #define rep(s,t) for(int i=s;i<=t;i++) #define ren for(int i=first[x];i!=-1;i=next[i]) using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } const int maxn=200010; int l[maxn],fa[maxn],to[maxn][2],last=1,cnt=1; void extend(int c) { int p,q,np,nq; p=last;l[np=last=++cnt]=l[p]+1; for(;!to[p][c];p=fa[p]) to[p][c]=np; if(!p) fa[np]=1; else { q=to[p][c]; if(l[p]+1==l[q]) fa[np]=q; else { l[nq=++cnt]=l[p]+1; memcpy(to[nq],to[q],sizeof(to[nq])); fa[nq]=fa[q]; fa[q]=fa[np]=nq; for(;to[p][c]==q;p=fa[p]) to[p][c]=nq; } } } char s[maxn]; int main() { scanf("%s",s);int n=strlen(s),p=1,ans=0,cur=0; rep(0,n-1) extend(s[i]-'a'); scanf("%s",s);n=strlen(s); rep(0,n-1) { int c=s[i]-'a'; if(to[p][c]) p=to[p][c],cur++; else { while(p&&!to[p][c]) p=fa[p]; if(!p) p=1,cur=0; else cur=l[p]+1,p=to[p][c]; } ans=max(ans,cur); } printf("%d\n",ans); return 0; }