Description
给出两个字符串,求最长公共子串.
Sol
SAM.
这题随便做啊...后缀数组/Hash+二分都可以.
SAM就是模板啊...直接在SAM上跑就行,没有了 (go[w]) 就往 (par) 跳.
每走一步统计一下答案.
Code
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int N = 250005; struct State{ State *par,*go[26]; int val; State(int _val):par(0),val(_val){ memset(go,0,sizeof(go)); } }*rt,*lst; void extend(int w){ State *p=lst,*np=new State(p->val+1); while(p && p->go[w]==0) p->go[w]=np,p=p->par; if(!p) np->par=rt; else{ State *q=p->go[w]; if(q->val == p->val+1) np->par=q; else{ State *nq=new State(p->val+1); memcpy(nq->go,q->go,sizeof(q->go)); nq->par=q->par; np->par=q->par=nq; while(p && p->go[w] == q) p->go[w]=nq,p=p->par; } }lst=np; } char A[N],B[N]; int la,lb,ans,len; void work(){ State *t=rt; for(int i=0;i<lb;i++){ for(;t && !t->go[B[i]-'a'];len=(t=t->par) ? t->val : 0); if(t && t->go[B[i]-'a']) t=t->go[B[i]-'a'],len++;else t=rt; ans=max(ans,len); } } int main(){ rt=new State(0),lst=rt; scanf("%s%s",A,B); la=strlen(A),lb=strlen(B); for(int i=0;i<la;i++) extend(A[i]-'a'); work(); return cout<<ans<<endl,0; }