首页 > 代码库 > 【hihocoder】sam-3

【hihocoder】sam-3

把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]);
}

 

【hihocoder】sam-3