bzoj 3998: [TJOI2015]弦论
2015-07-01 21:38
393 查看
Description
对于一个给定长度为N的字符串,求它的第K小子串是什么。Input
第一行是一个仅由小写英文字母构成的字符串S第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个。T=1则表示不同位置的相同子串算作多个。K的意义如题所述。
Output
输出仅一行,为一个数字串,为第K小的子串。如果子串数目不足K个,则输出-1Sample Input
aabc0 3
Sample Output
aabHINT
N<=5*10^5T<2
K<=10^9
建出后缀自动机,然后在后缀自动机上跑一下就可以。
维护后面有几种情况
切记虚点处置为0。。
#include<cstdio> #include<string> #include<cstring> #include<iostream> using namespace std; int T; int lx; struct sam { int son[1000005][26],pre[1000005],step[1000005]; int v[1000005],q[1000005]; int s[1000005],sum[1000005]; int last,tot; sam() { last=1; tot=1; } inline void push_back(int v) { tot++; step[tot]=v; } inline void extend(int x) { push_back(step[last]+1); int p=last,np=tot;s[np]=1; while(son[p][x]==0&&p!=0) { son[p][x]=np; p=pre[p]; } if(p==0) pre[np]=1; else { int q=son[p][x]; if(step[q]!=step[p]+1) { push_back(step[p]+1); //tot++; int nq=tot; int i; for(i=0;i<=25;i++) son[nq][i]=son[q][i]; pre[nq]=pre[q]; pre[q]=pre[np]=nq; while(son[p][x]==q) { son[p][x]=nq; p=pre[p]; } } else pre[np]=q; } last=np; } inline void build() { string x; cin>>x; lx=x.size(); int i; for(i=0;i<=lx-1;i++) extend(x[i]-'a'); } inline void prep() { int i,j; for(i=1;i<=tot;i++) v[step[i]]++; for(i=1;i<=tot;i++) v[i]+=v[i-1]; for(i=tot;i>=1;i--) q[v[step[i]]--]=i; // for(i=1;i<=tot;i++) // s[i]=1; for(i=tot;i>=1;i--) { if(T==1) s[pre[q[i]]]+=s[q[i]]; else s[q[i]]=1; } s[1]=0; for(i=tot;i>=1;i--) { sum[q[i]]+=s[q[i]]; for(j=0;j<=25;j++) sum[q[i]]+=sum[son[q[i]][j]]; } } inline void dfs(int d,int k) { if(k<=s[d]) return ; k-=s[d]; int i; for(i=0;i<=25;i++) { int t=son[d][i]; if(t!=0) { if(k<=sum[t]) { printf("%c",i+'a'); dfs(t,k); return ; } k-=sum[t]; } } } }sam; int main() { //freopen("data.in","r",stdin); //freopen("data.out","w",stdout); sam.build(); int k; scanf("%d%d",&T,&k); sam.prep(); if(k>sam.sum[1]) printf("-1\n"); else { sam.dfs(1,k); printf("\n"); } return 0; }
相关文章推荐
- PortQry
- JavaScript中的数组
- 成功CRS启动的系统日志
- 神经网络中的Early Stop
- 【LeetCode 201】Bitwise AND of Numbers Range
- Stanford UFLDL教程 池化Pooling
- 前端优化:DNS预解析提升页面速度
- 【组合】Bzoj3142 数列[HNOI2013]
- ListView设置emptyView的限制
- 程序员必须知道的8大排序和3大查找
- 黑马day11 装饰类
- Hadoop中两表JOIN的处理方法
- unity 随笔
- Android Busybox 下的adb,linux shell命令整理备忘 (2012-03-06 21:41:27)
- 仿51用车 Ipad版
- 1012. 数字分类 (20)
- LeetCode之Longest Palindromic Substring
- 迭代器
- python脚本二
- 对Navigation基础的了解