bzoj3998 弦论

好久没写SAM了,复习一下

/**************************************************************
    Problem: 3998
    User: Clare
    Language: C++
    Result: Accepted
    Time:7520 ms
    Memory:127252 kb
****************************************************************/
 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
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;ival]++;
    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;
}


你可能感兴趣的:(后缀自动机)