3998: [TJOI2015]弦论
题解:
每个点的size值就是这个从根-它出现的次数
如果相同只算一次就全部赋值为1就可以了
代码:
#include <bits/stdc++.h> #define ll long long #define rint register ll #define rep(i,h,t) for (rint i=h;i<=t;i++) #define dep(i,t,h) for (rint i=t;i>=h;i--) using namespace std; const ll N=1.1e6; char s[N]; ll size[N],len[N],ch[N][26],sum[N]; ll lst=1,node=1,t[N],a[N],fa[N],T,k; void extend(ll c) { ll f=lst,p=++node; lst=p; len[p]=len[f]+1; size[p]=1; while (f&&!ch[f][c]) ch[f][c]=p,f=fa[f]; if (!f) { fa[p]=1; return;}; ll x=ch[f][c],y=++node; if (len[f]+1==len[x]) {fa[p]=x; node--;return;}; len[y]=len[f]+1; fa[y]=fa[x]; fa[x]=fa[p]=y; memcpy(ch[y],ch[x],sizeof(ch[x])); while (f&&ch[f][c]==x) ch[f][c]=y,f=fa[f]; } void dfs(ll x) { if (k<=size[x]) { k=0; return; } k-=size[x]; rep(i,0,25) { ll y=ch[x][i]; if (k<=sum[y]) { char cc=i+'a'; cout<<cc; dfs(y); return; } else k-=sum[y]; } } int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); ios::sync_with_stdio(false); cin>>s; cin>>T>>k; ll l=strlen(s); rep(i,1,l) extend(s[i-1]-'a'); rep(i,1,node) t[len[i]]++; rep(i,1,node) t[i]+=t[i-1]; rep(i,1,node) a[t[len[i]]--]=i; dep(i,node,1) { ll x=a[i]; if (T) size[fa[x]]+=size[x]; else size[x]=1; } size[0]=size[1]=0; dep(i,node,1) { ll x=a[i]; sum[x]+=size[x]; rep(j,0,25) sum[x]+=sum[ch[x][j]]; } dfs(1); if (k) cout<<-1<<endl; return 0; }