题解:
后缀自动机
先把A的后缀自动机建好
然后用B再上面跑
如果不能转移就跳fail
如果可以就到下一个可行状态
代码:
#include<bits/stdc++.h> using namespace std; const int N=250005; char b[N],a[N]; int n,m,cnt,la; struct State { int ch[26],fa,len; void init() { fa=-1; len=0; memset(ch,-1,sizeof ch); } }T[N*2]; void Extend(int c) { int end=++cnt,tmp=la; T[end].init(); T[end].len=T[tmp].len+1; while (tmp!=-1&&T[tmp].ch[c]==-1) { T[tmp].ch[c]=end; tmp=T[tmp].fa; } if (tmp==-1)T[end].fa=0; else { int ne=T[tmp].ch[c]; if (T[tmp].len+1==T[ne].len)T[end].fa=ne; else { int np=++cnt; T[np]=T[ne]; T[np].len=T[tmp].len+1; T[end].fa=T[ne].fa=np; while (tmp!=-1&&T[tmp].ch[c]==ne) { T[tmp].ch[c]=np; tmp=T[tmp].fa; } } } la=end; } void solve() { int ans=0; T[0].init(); for (int i=1;i<=n;i++)Extend(a[i]-'a'); int Lcs=0,o=0; for (int i=1;i<=m;i++) { int c=b[i]-'a'; if (T[o].ch[c]!=-1) { o=T[o].ch[c]; ans=max(ans,++Lcs); } else { while (o!=-1&&T[o].ch[c]==-1)o=T[o].fa; if (o==-1)o=Lcs=0; else { Lcs=T[o].len+1; o=T[o].ch[c]; ans=max(ans,Lcs); } } } printf("%d ",ans); } int main() { scanf("%s%s",a+1,b+1); n=strlen(a+1); m=strlen(b+1); solve(); return 0; }