bzoj3998 弦论

来源:互联网 发布:淘宝3c认证编号 编辑:程序博客网 时间:2024/06/05 20:02

好久没写SAM了,复习一下

/**************************************************************    Problem: 3998    User: Clare    Language: C++    Result: Accepted    Time:7520 ms    Memory:127252 kb****************************************************************/ #include <cstdio>#include <iostream>#include <algorithm>#include <cmath>#include <cstring>#include <queue>#include <vector>using namespace std; #define N 500010 int n,T,K,Ws[N*2],cnt;char S[N],Ans[N];struct SAM{    SAM *fa,*son[26];    int val,size,sum;    void S_clear(){        fa=0;val=0;size=0;sum=0;        memset(son,0,sizeof(son));    }}*root,*last,State[N*2],*tot,*pos[N*2]; void Init(){    tot=State;root=last=tot++;    root->S_clear();} void Insert(int w){    SAM *p=last,*np=tot++;np->S_clear();    np->val=p->val+1;np->size=1;    while(p&&!p->son[w])        p->son[w]=np,p=p->fa;    if(p==0)        np->fa=root;    else    {        SAM *q=p->son[w];        if(q->val==p->val+1)            np->fa=q;        else        {            SAM *nq=tot++;nq->S_clear();            nq->val=p->val+1;            memcpy(nq->son,q->son,sizeof(q->son));            nq->fa=q->fa;q->fa=nq;np->fa=nq;            while(p&&p->son[w]==q)                p->son[w]=nq,p=p->fa;        }    }    last=np;} void DFS(SAM *p,int k){    if(k<=p->size)        return;    k-=p->size;    for(int i=0;i<26;i++)    {        if(p->son[i])        {            if(k<=p->son[i]->sum)            {                Ans[cnt++]='a'+i;                DFS(p->son[i],k);                return;            }            k-=p->son[i]->sum;        }    }} int main(){    scanf("%s",S);    n=(int)strlen(S);    Init();    for(int i=0;i<n;i++)        Insert(S[i]-'a');    int qwer=(int)(tot-State);    scanf("%d%d",&T,&K);    for(SAM *p=State;p!=tot;p++)        Ws[p->val]++;    for(int i=1;i<=n;i++)        Ws[i]+=Ws[i-1];    for(SAM *p=State;p!=tot;p++)        pos[--Ws[p->val]]=p;    for(int i=qwer-1;i>=0;i--)    {        SAM *p=pos[i];        if(T==0)            p->size=1;        else if(p->fa)            p->fa->size+=p->size;    }    root->size=0;    for(int i=qwer-1;i>=0;i--)    {        SAM *p=pos[i];        p->sum=p->size;        for(int j=0;j<26;j++)        {            if(p->son[j])                p->sum+=p->son[j]->sum;        }    }    if(K>root->sum)        puts("-1");    else    {        DFS(root,K);        Ans[cnt]=0;puts(Ans);    }    return 0;}


0 0