SPOJ 1812 LCS2
题解:
和上一题差不多
每个点记录前面的到这个点的最大值
初值赋为len[i]
然后注意要用子节点更新父节点
代码:
#include <bits/stdc++.h> #define ll long long #define rint register int #define rep(i,h,t) for (rint i=h;i<=t;i++) #define dep(i,t,h) for (rint i=t;i>=h;i--) #define me(x) memset(x,0,sizeof(x)) using namespace std; const int N=3e6; const int INF=1e9; char s[N]; int size[N],len[N],ch[N][26]; int lst=1,node=1,t[N],a[N],fa[N],ans[N],ans2[N],num[N]; void extend(int c) { int f=lst,p=++node; lst=p; len[p]=len[f]+1; size[p]=1; while (f&&!ch[f][c]) ch[f][c]=p,f=fa[f]; if (!f) { fa[p]=1; return;}; int x=ch[f][c],y=++node; if (len[f]+1==len[x]) {fa[p]=x; node--;return;}; len[y]=len[f]+1; fa[y]=fa[x]; fa[x]=fa[p]=y; memcpy(ch[y],ch[x],sizeof(ch[x])); while (f&&ch[f][c]==x) ch[f][c]=y,f=fa[f]; } void js() { int l=strlen(s),now=1,t=0; rep(i,1,l) { int x=s[i-1]-'a'; if (ch[now][x]) now=ch[now][x],++t; else { while (now&&!ch[now][x]) now=fa[now]; if (!now) now=1,t=0; else t=len[now]+1,now=ch[now][x]; } ans[now]=max(ans[now],t); } } int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); ios::sync_with_stdio(false); cin>>s; int l=strlen(s); rep(i,1,l) extend(s[i-1]-'a'); rep(i,1,node) t[len[i]]++; rep(i,1,node) t[i]+=t[i-1]; rep(i,1,node) a[t[len[i]]--]=i; rep(i,1,N-1) ans2[i]=len[i]; while (cin>>s) { me(ans); js(); dep(i,node,1) { int x=a[i]; ans2[x]=min(ans2[x],ans[x]); ans[fa[x]]=max(ans[fa[x]],ans[x]); } } int maxn=0; rep(i,1,node) maxn=max(maxn,ans2[i]); cout<<maxn<<endl; return 0; }