spoj1811 LCS - Longest Common Substring
分析
我们可以建出s串的parent树
然后t串在上面跳着找即可
代码
#include<bits/stdc++.h>
using namespace std;
char s[300100],t[300100];
int n,m,Ans;
struct SAM {
int mp[1000100][30],fa[1000100],ed=1,ccnt=1,len[1000100];
int cnt,head[1000100],nxt[1000100],to[1000100];
inline void ins(int x,int n1){
int p=ed;
ed=++ccnt;
len[ccnt]=n1;
while(p&&!mp[p][x]){
mp[p][x]=ed;
p=fa[p];
}
if(!p){
fa[ed]=1;
return;
}
int q=mp[p][x];
if(len[p]+1==len[q]){
fa[ed]=q;
return;
}
len[++ccnt]=len[p]+1;
for(int i=1;i<=26;i++)mp[ccnt][i]=mp[q][i];
fa[ccnt]=fa[q];
fa[q]=ccnt;
fa[ed]=ccnt;
for(int i=p;mp[p][x]==q;i=fa[i])mp[i][x]=ccnt;
}
inline void add(int x,int y){nxt[++cnt]=head[x];head[x]=cnt;to[cnt]=y;}
inline void build(){for(int i=2;i<=n;i++)add(fa[i],i);}
inline void work(){
int p=1,res=0;
for(int i=1;i<=m;i++){
int x=t[i]-'a'+1;
if(mp[p][x])res++,p=mp[p][x];
else {
while(p&&!mp[p][x])p=fa[p];
if(p)res=len[p]+1,p=mp[p][x];
else res=0,p=1;
}
Ans=max(Ans,res);
}
}
};
SAM sam;
int main(){
int i,j,k;
scanf("%s%s",s+1,t+1);
n=strlen(s+1);
m=strlen(t+1);
for(i=1;i<=n;i++)sam.ins(s[i]-'a'+1,i);
sam.build();
sam.work();
printf("%d\n",Ans);
return 0;
}