【TJOI2015】bzoj3998 弦论

来源:互联网 发布:python json 字符串 编辑:程序博客网 时间:2024/06/03 19:54

先统计出每个节点代表的子串个数,如果去重就是1,不去重就是right集合的大小。因为后缀自动机是一个DAG,可以预处理子节点大小之和然后dfs一遍。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define LL long longconst int maxn=1000010;char s[maxn];int trans[maxn][27],fail[maxn],val[maxn],cnt[maxn],que[maxn],n,t,k,tot=1;LL size[maxn],num[maxn];int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int last=1,p,np,q,nq,x;    scanf("%s%d%d",s+1,&t,&k);    n=strlen(s+1);    for (int i=1;i<=n;i++)    {        x=s[i]-'a'+1;        p=last;        val[last=np=++tot]=val[p]+1;        while (p&&!trans[p][x])        {            trans[p][x]=np;            p=fail[p];        }        if (!p) fail[np]=1;        else        {            q=trans[p][x];            if (val[q]==val[p]+1) fail[np]=q;            else            {                val[nq=++tot]=val[p]+1;                fail[nq]=fail[q];                fail[np]=fail[q]=nq;                for (int j=1;j<=26;j++) trans[nq][j]=trans[q][j];                while (p&&trans[p][x]==q)                {                    trans[p][x]=nq;                    p=fail[p];                }            }        }    }    for (int i=1;i<=tot;i++) cnt[val[i]]++;    for (int i=1;i<=n;i++) cnt[i]+=cnt[i-1];    for (int i=1;i<=tot;i++) que[cnt[val[i]]--]=i;    if (t)    {        p=1;        for (int i=1;i<=n;i++)        {            p=trans[p][s[i]-'a'+1];            num[p]++;        }        for (int i=tot;i;i--) num[fail[que[i]]]+=num[que[i]];        num[1]=0;    }    else for (int i=2;i<=tot;i++) num[i]=1;    for (int i=tot;i;i--)    {        size[que[i]]=num[que[i]];        for (int j=1;j<=26;j++)            size[que[i]]+=size[trans[que[i]][j]];    }    if (size[1]<k)    {        printf("-1\n");        return 0;    }    p=1;    while (k>num[p])    {        k-=num[p];        for (int j=1;j<=26;j++)            if (trans[p][j])            {                if (k>size[trans[p][j]]) k-=size[trans[p][j]];                else                {                    printf("%c",'a'+j-1);                    p=trans[p][j];                    break;                }            }    }}
原创粉丝点击