bzoj3998: [TJOI2015]弦论
SAM小裸题qwq
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <algorithm> #define N 1000006 using namespace std; int OP; struct SAM{ int val[N],sum[N]; #define u q[i] struct SAMnode{ int par,mx,go[26]; } t[N]; int last,size; int newnode(int _mx){ t[++size].par=0;t[size].mx=_mx;val[size]=0; memset(t[size].go,0,sizeof(t[size].go)); return size; } void clear(){size=0;last=newnode(0);} void extend(char c){ c-='a'; int p=last,np=newnode(t[p].mx+1); for (;p&&!t[p].go[c];p=t[p].par) t[p].go[c]=np; if (!p) t[np].par=1; else{ int q=t[p].go[c]; if (t[p].mx+1==t[q].mx) t[np].par=q; else{ int nq=newnode(t[p].mx+1); memcpy(t[nq].go,t[q].go,sizeof(t[q].go)); t[nq].par=t[q].par; t[q].par=t[np].par=nq; for (;p&&t[p].go[c]==q;p=t[p].par) t[p].go[c]=nq; } } last=np; val[last]=1; } int v[N],q[N]; void precompute(){ memset(v,0,sizeof(v)); for (int i=1;i<=size;++i) ++v[t[i].mx]; for (int i=1;i<=size;++i) v[i]+=v[i-1]; for (int i=size;i;--i) q[v[t[i].mx]--]=i; if (!OP) for (int i=1;i<=size;++i) val[i]=1; else for (int i=size;i;--i) val[t[u].par]+=val[u]; val[1]=0; for (int i=size;i;--i){ sum[u]=val[u]; for (int j=0;j<26;++j)if (t[u].go[j]) sum[u]+=sum[t[u].go[j]]; } } void solve(int p,int k){ if ((k-=val[p])<=0) return; for (int i=0;i<26;++i)if (t[p].go[i]){ if (sum[t[p].go[i]]>=k){ putchar('a'+i); solve(t[p].go[i],k); return; } k-=sum[t[p].go[i]]; } printf("-1"); } } sam; char st[N]; int main(){ scanf("%s",st); sam.clear(); for (int i=0;st[i];++i) sam.extend(st[i]); int K;scanf("%d%d",&OP,&K); sam.precompute(); sam.solve(1,K);puts(""); return 0; }