把Parent Tree拓扑排序下,然后从下往上合并。
具体的看官方题解啦~
#include<bits/stdc++.h> #define N 1000010 using namespace std; int n;char s[N]; int tot=0,head[N<<1]; struct Edge{int u,v,next;}G[N<<1]; int size[N<<1],ans[N]; struct Suffix_Automaton{ int fa[N<<1],ch[N<<1][30],l[N<<1],r[N<<1],rt,cnt,last; Suffix_Automaton(){cnt=last=1;rt=1;} void ins(int c){ int p=last,np=++cnt;last=np;l[np]=l[p]+1; for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np; if(!p){fa[np]=rt;r[np]=1;} else{ int q=ch[p][c]; if(l[p]+1==l[q]){fa[np]=q;r[np]=l[q]+1;} else{ int nq=++cnt;l[nq]=l[p]+1; memcpy(ch[nq],ch[q],sizeof(ch[q])); fa[nq]=fa[q];r[nq]=l[fa[q]]+1; fa[q]=fa[np]=nq;r[q]=r[np]=l[nq]+1; for(;p&&ch[p][c]==q;p=fa[p])ch[p][c]=nq; } } } }sam; inline void addedge(int u,int v){ G[++tot].u=u;G[tot].v=v;G[tot].next=head[u];head[u]=tot; } void dfs(int u){ for(int i=head[u];i;i=G[i].next){ int v=G[i].v;dfs(v); size[u]+=size[v]; } if(!head[u])size[u]=1; } int main(){ scanf("%s",s+1);n=strlen(s+1); sam.ins(0); for(int i=1;i<=n;i++)sam.ins(s[i]-‘a‘+1); for(int i=2;i<=sam.cnt;i++)addedge(sam.fa[i],i);dfs(1); for(int i=2;i<=sam.cnt;i++)ans[sam.l[i]]=max(ans[sam.l[i]],size[i]); for(int i=n-1;i;i--)ans[i]=max(ans[i],ans[i+1]); for(int i=1;i<=n;i++)printf("%d\n",ans[i]); }
时间: 2024-10-09 01:50:45