题意:
给你一个字符串,Q次询问所有本质不同的子串中,第k小的子串。
题解:
这道题和[P3975 [TJOI2015]弦论]一样,只是这道题要求更少,所以这篇就给个传送门吧,主要是懒…
A C AC AC代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5+50;
char s[MAXN];
struct Suffix{
int nxt[MAXN][26],fa[MAXN],len[MAXN];
int a[MAXN],c[MAXN],sz[MAXN],sum[MAXN];
int tot=1,last=1;
inline void Insert(int x){
int p = last,np = ++tot;
last = np,len[np] = len[p] + 1;
for(;p && !nxt[p][x];p=fa[p]) nxt[p][x] = np;
if(!p) fa[np] = 1;
else {
int q = nxt[p][x];
if(len[p]+1==len[q]) fa[np] = q;
else {
int nq = ++tot;
len[nq] = len[p] + 1;
memcpy(nxt[nq],nxt[q],sizeof(nxt[q]));
fa[nq] = fa[q];
fa[q] = fa[np] = nq;
for(;nxt[p][x]==q;p=fa[p]) nxt[p][x] = nq;
}
}
}
inline void Sort(int n){
for(int i=1;i<=tot;i++) c[len[i]]++;
for(int i=1;i<=n;i++) c[i]+=c[i-1];
for(int i=1;i<=tot;i++) a[c[len[i]]--]=i;
for(int i=tot;i;i--) sz[a[i]]=1;
sz[1] = 0;
for(int i=tot;i;i--){
sum[a[i]] = sz[a[i]];
for(int j=0;j<26;j++)
sum[a[i]] += sum[nxt[a[i]][j]];
}
}
inline void Solve(int k){
int u = 1;
//if(k > sum[1]) { puts("-1");return; }
while(k>0){
int p = 0;
while(k>sum[nxt[u][p]])
k-=sum[nxt[u][p]],p++;
u = nxt[u][p];
putchar(p+'a');
k -= sz[u];
}
puts("");
}
}SAM;
int main(){
scanf("%s",s+1);
int n = strlen(s+1);
for(int i=1;i<=n;i++) SAM.Insert(s[i]-'a');
SAM.Sort(n);
int Q,k; scanf("%d",&Q);
while(Q--){
scanf("%d",&k);
SAM.Solve(k);
}
return 0;
}