%%%陈老师%%%
神奇的后缀自动机。。。看陈老师的WC讲稿PPT真的是每一页都有无穷无尽的信息量%%%
搭配15年某(两位?)神犇的的集训队论文一起食用味道更好哟%%%
这种照抄黄学长板子我自己都没怎么搞清楚的东西就不放题解了。。。
/************************************************************** Problem: 3998 User: RicardoWang Language: C++ Result: Accepted Time:5248 ms Memory:130668 kb ****************************************************************/ #include<cstdlib> #include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<vector> using namespace std; #define WJMZBMR_OTZ true #define maxn 500005 int T,k,len; char s[maxn]; struct Sam { int last,cnt,chi[maxn*2][27],len[maxn*2],fa[maxn*2],val[maxn*2],sum[maxn*2]; int cc[maxn*2],q[maxn*2]; Sam() { cnt=0;last=++cnt; fa[last]=0;len[last]=0; } void extend(int x) { int np=++cnt,p=last;len[np]=len[p]+1; val[np]=1;last=np; while(!chi[p][x]&&p)chi[p][x]=np,p=fa[p]; if(!p)fa[np]=1; else { int q=chi[p][x]; if(len[q]==len[p]+1)fa[np]=q; else { int nq=++cnt; len[nq]=len[p]+1; memcpy(chi[nq],chi[q],sizeof(chi[nq])); fa[nq]=fa[q]; fa[q]=fa[np]=nq; while(chi[p][x]==q)chi[p][x]=nq,p=fa[p]; } } return ; } void ready(int L) { for(int i=1;i<=cnt;i++)cc[len[i]]++; for(int i=1;i<=L;i++)cc[i]+=cc[i-1]; for(int i=cnt;i>=1;i--)q[cc[len[i]]--]=i; int t; for(int i=cnt;i>=1;i--) { t=q[i]; if(!T) val[t]=1; else val[fa[t]]+=val[t]; } val[1]=0; for(int i=cnt;i>=1;i--) { t=q[i]; sum[t]=val[t]; for(int j=0;j<26;j++) { sum[t]+=sum[chi[t][j]]; } } return ; } void DFS(int now,int k) { if(k<=val[now])return ; else k-=val[now]; for(int i=0;i<26;i++) { if(k<=sum[chi[now][i]]) { putchar('a'+i); DFS(chi[now][i],k); return ; } else k-=sum[chi[now][i]]; } } }SAM; int main() { //freopen("in.txt","r",stdin); scanf("%s",s+1); len=strlen(s+1); scanf("%d%d",&T,&k); for(int i=1;i<=len;i++)SAM.extend(s[i]-'a'); SAM.ready(len); if(k>SAM.sum[1]){putchar('-');putchar('1');} else SAM.DFS(1,k); if( WJMZBMR_OTZ )putchar('\n'); return 0; }
%%%