BZOJ3998: [TJOI2015]弦论

【传送门:BZOJ3998


简要题意:

  对于一个给定长度为N的字符串,求它的第K小子串是什么


题解:

  后缀自动机

  首先对于T=0的时候,所有的能到达的不同状态,Right集合大小恒为1

  T=1的时候,就累加

  然后先判断子串数量是否超过K

  如果没有,则直接DFS就好了


参考代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
struct SAM
{
    int son[27],dep,fail;
}tr[1100000];int cnt,root,last;
int a[510000];
void add(int k)
{
    int x=a[k];
    int np=++cnt,p=last;
    tr[np].dep=k;
    while(p!=0&&tr[p].son[x]==0) tr[p].son[x]=np,p=tr[p].fail;
    if(p==0) tr[np].fail=root;
    else
    {
        int q=tr[p].son[x];
        if(tr[q].dep==tr[p].dep+1) tr[np].fail=q;
        else
        {
            int nq=++cnt;tr[nq]=tr[q];
            tr[nq].dep=tr[p].dep+1;
            tr[q].fail=tr[np].fail=nq;
            while(p!=0&&tr[p].son[x]==q) tr[p].son[x]=nq,p=tr[p].fail;
        }
    }
    last=np;
}
char st[510000];
int Rsort[510000],r[1100000],sum[1100000],sa[1100000];
int k;
void dfs(int x)
{
    if(k<=r[x]) return ;
    k-=r[x];
    for(int i=1;i<=26;i++)
    {
        int y=tr[x].son[i];
        if(y==0) continue;
        if(k>sum[y]) k-=sum[y];
        else
        {
            printf("%c",i+'a'-1);
            dfs(y);
            return ;
        }
    }
}
int main()
{
    scanf("%s",st+1);
    int len=strlen(st+1);
    cnt=last=root=1;
    for(int i=1;i<=len;i++) a[i]=st[i]-'a'+1,add(i);
    for(int i=1;i<=cnt;i++) Rsort[tr[i].dep]++;
    for(int i=1;i<=len;i++) Rsort[i]+=Rsort[i-1];
    for(int i=cnt;i>=1;i--) sa[Rsort[tr[i].dep]--]=i;
    int p=root;
    for(int i=1;i<=len;i++) p=tr[p].son[a[i]],r[p]++;
    int T;
    scanf("%d%d",&T,&k);
    for(int i=cnt;i>=1;i--)
    {
        if(T==0) r[tr[sa[i]].fail]=1;
        else r[tr[sa[i]].fail]+=r[sa[i]];
    }
    r[root]=0;
    for(int i=cnt;i>=1;i--)
    {
        int p=sa[i];sum[p]=r[p];
        for(int j=1;j<=26;j++) if(tr[p].son[j]!=0) sum[p]+=sum[tr[p].son[j]];
    }
    if(k>sum[root]) printf("-1");
    else dfs(root);
    printf("\n");
    return 0;
}

 

posted @ 2018-04-12 09:15  Star_Feel  阅读(161)  评论(0编辑  收藏  举报