zoukankan      html  css  js  c++  java
  • 【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
    ",ans[i]);
    }
  • 相关阅读:
    腾讯2016年实习生笔试题-蛇形数组-循环枚举遍历
    直接插入排序的加强版
    scanner 在java中的输入
    一种排序
    将string str中的str转换成字符数组
    呜呜呜
    ansible-playbook 实战案例 全网备份 实时备份
    Rsync服务实战
    TCP三次握手与四次握手
    centos 6.9修改系统默认字符集
  • 原文地址:https://www.cnblogs.com/zcysky/p/7019854.html
Copyright © 2011-2022 走看看