来自蒟蒻XXJ的做题记录
直接自动机写出来
然后求一下每次trans过后还有多少字串
然后在自动机上面走就行了
#include<bits/stdc++.h>
#define mem(i,j) memset(i,j,sizeof(i))
#define mcy(i,j) memcpy(i,j,sizeof(i))
using namespace std;
const int MAXN=90000*2+10;
int n;
struct SAM{
int trans[MAXN][26],fa[MAXN],lth[MAXN],siz[MAXN];
int cnt,last;
SAM(){
cnt=0;last=++cnt;
mem(trans,0);mem(fa,0);mem(lth,0);mem(siz,0);
}
void extend(int c){
int np=++cnt,p=last;last=cnt;
lth[np]=lth[p]+1;
for(;p&&!trans[p][c];p=fa[p]) trans[p][c]=np;
if(!p) fa[np]=1;
else{
int q=trans[p][c];
if(lth[q]==lth[p]+1) fa[np]=q;
else{
int nq=++cnt;lth[nq]=lth[p]+1;
mcy(trans[nq],trans[q]);
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
for(;p&&trans[p][c]==q;p=fa[p]) trans[p][c]=nq;
}
}
}
void build(char str[]){
int len=strlen(str);
for(int i=0;i<len;i++) extend(str[i]-'a');
}
}sam;
char c[MAXN];
int rank[MAXN],k,t;
bool cmp(int i,int j){
return sam.lth[i]>sam.lth[j];
}
void init(){
for(int i=1;i<=sam.cnt;++i) rank[i]=i;
sort(rank+1,rank+sam.cnt+1,cmp);
for(int i=1;i<=sam.cnt;i++){
int id=rank[i];
sam.siz[id]=1;
for(int j=0;j<26;j++) if(sam.trans[id][j]) sam.siz[id]+=sam.siz[sam.trans[id][j]];
}
}
void input(){
scanf("%s",c);
sam.build(c);
init();
}
void xxj(){
scanf("%d",&t);
while(t--){
scanf("%d",&k);
int p=1;
while(k){
for(int i=0;i<26;i++){
if(!sam.trans[p][i]) continue;
if(k<=sam.siz[sam.trans[p][i]]){
--k;p=sam.trans[p][i];
cout<<char('a'+i);
break;
}
else k-=sam.siz[sam.trans[p][i]];
}
}
printf("\n");
}
}
void hello(){
freopen("a.in","r",stdin);
freopen("a.ans","w",stdout);
}
int main(){
// hello();
input();
xxj();
return 0;
}