zoukankan      html  css  js  c++  java
  • LG P3975 [TJOI2015]弦论

    Description

    对于一个给定的长度为 n 的字符串,求出它的第 k 小子串是什么。

    Solution

    对字符串构建SAM,在parent树上求出每个点的endpos集合大小,再在正向边上求出所有子串个数,分本质不同和本质相同讨论

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int t,k,length,las=1,tot=1,f[1000005],g[1000005],buc[1000005],topo[1000005];
    char s[500005]; 
    struct Node
    {
        int ch[26],fa,len;
    }sam[1000005];
    inline int read()
    {
        int f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            w=(w<<1)+(w<<3)+ch-'0';
            ch=getchar();
        }
        return f*w;
    }
    void insert(int c)
    {
        int p=las,np=las=++tot;
        sam[np].len=sam[p].len+1;
        f[np]=1;
        for(;p&&!sam[p].ch[c];p=sam[p].fa)
        {
            sam[p].ch[c]=np;
        }
        if(!p)
        {
            sam[np].fa=1;
        }
        else
        {
            int q=sam[p].ch[c];
            if(sam[q].len==sam[p].len+1)
            {
                sam[np].fa=q;
            }
            else
            {
                int nq=++tot;
                sam[nq]=sam[q];
                sam[nq].len=sam[p].len+1;
                sam[q].fa=sam[np].fa=nq;
                for(;p&&sam[p].ch[c]==q;p=sam[p].fa)
                {
                    sam[p].ch[c]=nq;
                }
            }
        }
    }
    void print(int x,int n)
    {
        if(n<=f[x])
        {
            return;
        }
        n-=f[x];
        for(int i=0;i<26;i++)
        {
            int v=sam[x].ch[i];
            if(v)
            {
                if(n>g[v])
                {
                    n-=g[v];
                }
                else
                {
                    putchar(i+'a');
                    print(v,n);
                    return;
                }
            }
        }
    }
    int main()
    {
        scanf("%s",s);
        length=strlen(s);
        t=read();
        k=read();
        for(int i=0;i<length;i++)
        {
            insert(s[i]-'a');
        }
        for(int i=1;i<=tot;i++)
        {
            buc[sam[i].len]++;
        }
        for(int i=1;i<=tot;i++)
        {
            buc[i]+=buc[i-1];
        }
        for(int i=1;i<=tot;i++)
        {
            topo[buc[sam[i].len]--]=i;
        }
        for(int i=tot;i>=1;i--)
        {
            f[sam[topo[i]].fa]+=f[topo[i]];
        }
        if(!t)
        {
            for(int i=1;i<=tot;i++)
            {
                g[i]=f[i]=1;
            }
        }
        else
        {
            for(int i=1;i<=tot;i++)
            {
                g[i]=f[i];
            }
        }
        f[1]=g[1]=0;
        for(int i=tot;i>=1;i--)
        {
            for(int j=0;j<26;j++)
            {
                if(sam[topo[i]].ch[j])
                {
                    g[topo[i]]+=g[sam[topo[i]].ch[j]];
                }
            }
        }
        if(g[1]<k)
        {
            puts("-1");
        }
        else
        {
            print(1,k);
        }
        return 0;
    }
    [TJOI2015]弦论
  • 相关阅读:
    hdu_5855_Less Time, More profit(二分+最大权闭合图)
    hdu_5832_A water problem(模拟)
    poj_3261_Milk Patterns(后缀数组)
    [bzoj1072][SCOI2007]排列(状态压缩DP)
    [bzoj1597][USACO2008]土地购买(DP斜率优化/四边形优化)
    [bzoj1293][SCOI2009]生日礼物(单调队列)
    [bzoj 2463]谁能赢呢?(博弈论)
    矩阵快速幂优化递推总结
    [bzoj1563][NOI2009]诗人小G(决策单调性优化)
    [bzoj1821][JSOI2010]部落划分(贪心)
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/13406369.html
Copyright © 2011-2022 走看看