首页 > 代码库 > 后缀自动机
后缀自动机
BZOJ3998
#include <cstdio> #include <cstring> using namespace std; int last,dis[1000011],fa[1000011],a[1000011][26],cnt,sum[1000011]; int val[1000011],n,dl[1000011],T,k; char st[1000011]; void ins(int num){ int p=last,np=last=++cnt; dis[np]=dis[p]+1;val[np]=1; while (!a[p][num]&&p) a[p][num]=np,p=fa[p]; if (!p) fa[np]=1;else{ int q=a[p][num]; if (dis[p]+1==dis[q]) fa[np]=q;else{ int nq=++cnt;dis[nq]=dis[p]+1; memcpy(a[nq],a[q],sizeof(a[q])); fa[nq]=fa[q]; fa[q]=fa[np]=nq; while (a[p][num]==q) a[p][num]=nq,p=fa[p]; } } } void init(){ for (int i=1;i<=cnt;i++) sum[dis[i]]++; for (int i=1;i<=n;i++) sum[i+1]+=sum[i]; for (int i=cnt;i>0;i--) dl[sum[dis[i]]--]=i; for (int i=1;i<=cnt;i++) sum[i]=0; for (int i=cnt;i>0;i--){ int t=dl[i]; if (T==1) val[fa[t]]+=val[t];else val[t]=1; } val[1]=0; for (int i=cnt;i>0;i--){ int t=dl[i];sum[t]=val[t]; for (int j=0;j<26;j++) sum[t]+=sum[a[t][j]]; } } void dfs(int po,int num){ if (num<=val[po]) return; num-=val[po]; for (int i=0;i<26;i++) if (a[po][i]){ if (num<=sum[a[po][i]]){ putchar(‘a‘+i); dfs(a[po][i],num); return; } num-=sum[a[po][i]]; } } int main(){ scanf("%s",&st); scanf("%d%d",&T,&k); last=cnt=1;dis[1]=1;n=strlen(st); for (int i=0;i<n;i++) ins(st[i]-‘a‘); init(); if (k>sum[1]) printf("-1\n");else dfs(1,k); }
后缀自动机
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。