BZOJ - 3998 弦论 (后缀自动机)
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 using namespace std; 5 typedef long long ll; 6 const int N=1e6+10,M=26; 7 char s[N],s2[N]; 8 int n,f,k; 9 struct SAM { 10 int go[N][M],pre[N],mxl[N],c[N],ss[N],tot,last,siz[N],sum[N],vis[N],mx; 11 void init() {last=tot=0; newnode(0); pre[0]=-1;} 12 int newnode(int l) { 13 int u=tot++; 14 memset(go[u],0,sizeof go[u]); 15 mxl[u]=l,siz[u]=0; 16 return u; 17 } 18 void add(int ch) { 19 int p=last,np=last=newnode(mxl[p]+1); 20 siz[np]=1; 21 for(; ~p&&!go[p][ch]; p=pre[p])go[p][ch]=np; 22 if(!~p)pre[np]=0; 23 else { 24 int q=go[p][ch]; 25 if(mxl[q]==mxl[p]+1)pre[np]=q; 26 else { 27 int nq=newnode(mxl[p]+1); 28 memcpy(go[nq],go[q],sizeof go[nq]); 29 pre[nq]=pre[q],pre[q]=pre[np]=nq; 30 for(; ~p&&go[p][ch]==q; p=pre[p])go[p][ch]=nq; 31 } 32 } 33 } 34 void build(char* s,int n) {init(); for(int i=0; i<n; ++i)add(s[i]-'a');} 35 void toposort() { 36 for(int i=0; i<tot; ++i)c[i]=0; 37 for(int i=0; i<tot; ++i)++c[mxl[i]]; 38 for(int i=1; i<tot; ++i)c[i]+=c[i-1]; 39 for(int i=0; i<tot; ++i)ss[--c[mxl[i]]]=i; 40 } 41 void getsiz() { 42 for(int i=tot-1; i>0; --i)siz[pre[ss[i]]]+=siz[ss[i]]; 43 siz[0]=0; 44 } 45 void getsum() { 46 for(int i=0; i<tot; ++i)sum[i]=siz[i]; 47 for(int i=tot-1; i>=0; --i) 48 for(int j=0; j<M; ++j)if(go[ss[i]][j])sum[ss[i]]+=sum[go[ss[i]][j]]; 49 } 50 void qry(int u,int k) { 51 int dep; 52 for(dep=0; k>siz[u]; ++dep) { 53 k-=siz[u]; 54 for(int i=0; i<M; ++i) { 55 int v=go[u][i]; 56 if(!v)continue; 57 if(k<=sum[v]) {s2[dep]=i+'a',u=v; break;} 58 k-=sum[v]; 59 } 60 } 61 s2[dep]=0,puts(s2); 62 } 63 void run() { 64 build(s,n); 65 toposort(); 66 if(f)getsiz(); 67 else {for(int i=1; i<tot; ++i)siz[i]=1; siz[0]=0;} 68 getsum(); 69 if(sum[0]<k)puts("-1"); 70 else qry(0,k); 71 } 72 } sam; 73 int main() { 74 scanf("%s%d%d",s,&f,&k),n=strlen(s); 75 sam.run(); 76 return 0; 77 }