好久沒寫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;
}