SP1811 LCS最長公共子串 題解
阿新 • • 發佈:2022-05-18
給一個串建 SAM,另一個串在上面跑。
點選檢視程式碼
const int N=2.5e5+13; char s[N],t[N]; int nxt[N<<1],len[N<<1],ptot=1,lastpos=1; std::unordered_map<int,int> son[N<<1],boom; inline int newpos(std::unordered_map<int,int> nson,int nlen){return len[++ptot]=nlen,std::swap(son[ptot],nson),ptot;} inline void insert(int c){ int p=lastpos;int u=newpos(boom,len[p]+1); while(p&&son[p].find(c)==son[p].end()) son[p][c]=u,p=nxt[p]; lastpos=u; if(!p) return nxt[u]=1,void(); int d=son[p][c]; if(len[d]==len[p]+1) nxt[u]=d; else{ int v=newpos(son[d],len[p]+1); nxt[v]=nxt[d],nxt[d]=nxt[u]=v; while(p&&son[p][c]==d) son[p][c]=v,p=nxt[p]; } } int main(){ read(s+1),read(t+1); int n=strlen(s+1),m=strlen(t+1); for(int i=1;i<=n;++i) insert(s[i]-'a'); int i=1,p=1,now=0,ans=0; while(i<=m){ int c=t[i]-'a'; while(p!=1&&son[p].find(c)==son[p].end()) p=nxt[p],now=len[p]; if(son[p].find(c)!=son[p].end()) p=son[p][c],++now; chkmax(ans,now); ++i; } println(ans); return 0; }