代码参考:http://blog.csdn.net/qq_33229466/article/details/79140428
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; const int maxn=400005; int n,mx[maxn],ch[maxn][26],fa[maxn],last=1,id[maxn],tot=1; int dp[maxn],pos[maxn],cnt,b[maxn],c[maxn],root[maxn],ans; char s[maxn]; struct node{ int l,r; }tr[maxn*50]; void add(int i,int x){ int p,q,np,nq; p=last;last=np=++tot;mx[np]=mx[p]+1;id[np]=i; for(;!ch[p][x]&&p;p=fa[p])ch[p][x]=np; if(!p)fa[np]=1; else{ q=ch[p][x]; if(mx[q]==mx[p]+1)fa[np]=q; else{ nq=++tot;mx[nq]=mx[p]+1;id[nq]=i; memcpy(ch[nq],ch[q],sizeof(ch[q])); fa[nq]=fa[q]; fa[q]=fa[np]=nq; for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq; } } } void ins(int &d,int l,int r,int x){ if(!d)d=++cnt; if(l==r)return; int mid=l+r>>1; if(x<=mid)ins(tr[d].l,l,mid,x); else ins(tr[d].r,mid+1,r,x); } int merge(int x,int y){ if(!x||!y)return x+y; int d=++cnt; tr[d].l=merge(tr[x].l,tr[y].l); tr[d].r=merge(tr[x].r,tr[y].r); return d; } bool query(int d,int l,int r,int x,int y){ if(!d)return 0; if(l==x&&r==y)return 1; int mid=l+r>>1; if(x<=mid&&query(tr[d].l,l,mid,x,min(y,mid)))return 1; if(y>mid&&query(tr[d].r,mid+1,r,max(x,mid+1),y))return 1; return 0; } void build(){ for(int i=1;i<=tot;++i)b[mx[i]]++; for(int i=1;i<=tot;++i)b[i]+=b[i-1]; for(int i=tot;i>=1;--i)c[b[mx[i]]--]=i; for(int i=tot;i>=2;--i){ ins(root[c[i]],1,n,id[c[i]]); root[fa[c[i]]]=merge(root[fa[c[i]]],root[c[i]]); } } int main(){ cin>>n; scanf("%s",s+1); for(int i=1;i<=n;++i)add(i,s[i]-'a'); build(); ans=1; for(int i=2;i<=tot;++i){ int x=c[i]; if(fa[x]==1)dp[x]=1,pos[x]=x; else if(query(root[pos[fa[x]]],1,n,id[x]-mx[x]+mx[pos[fa[x]]],id[x]-1)){dp[x]=dp[fa[x]]+1;pos[x]=x;} else {dp[x]=dp[fa[x]];pos[x]=pos[fa[x]];} ans=max(ans,dp[x]); } cout<<ans; return 0; }