bzoj 3998: [TJOI2015]弦论
Description
对于一个给定长度为N的字符串,求它的第K小子串是什么。
Input
第一行是一个仅由小写英文字母构成的字符串S
第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个。T=1则表示不同位置的相同子串算作多个。K的意义如题所述。
Output
输出仅一行,为一个数字串,为第K小的子串。如果子串数目不足K个,则输出-1
solution
和 SPOJ7258 比较类似,只不过多了一个不同位置算多次,用到 SPOJNSUBSTR 的方法,因为父亲节点是当前节点的最大子集,所以在父亲节点出现过的,在当前节点一定出现过,所以直接将 \(size\) 累加到父亲节点上即可.
注意这个时候跳的过程需要做一些改变,每跳到一个位置 \(k\) 要减去当前节点的 \(size\),因为做了累加操作,也就是说含有这个子串的个数不止\(1\),当\(k<=0\)时即统计完毕
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=1200005;
char s[N];int fa[N],n,ch[N][27],T,K,len[N],cnt=1,size[N],t[N],p,cur=1;
void build(int c,int id){
p=cur;cur=++cnt;len[cur]=id;
for(;p && !ch[p][c];p=fa[p])ch[p][c]=cur;
if(!ch[p][c])fa[cur]=1;
else{
int q=ch[p][c];
if(len[p]+1==len[q])fa[cur]=q;
else{
int nt=++cnt;len[nt]=len[p]+1;
memcpy(ch[nt],ch[q],sizeof(ch[q]));
fa[nt]=fa[q];fa[q]=fa[cur]=nt;
for(;ch[p][c]==q;p=fa[p])ch[p][c]=nt;
}
}
size[cur]=1;
}
int c[N],sa[N];
void priwork(){
for(int i=1;i<=cnt;i++)c[len[i]]++;
for(int i=1;i<=n;i++)c[i]+=c[i-1];
for(int i=cnt;i>=1;i--)sa[c[len[i]]--]=i;
for(RG int i=cnt,x;i>=1;i--){
x=sa[i];
if(T)size[fa[x]]+=size[x];
else size[x]=1;
if(x!=1)t[x]=size[x];
for(RG int j=0;j<=25;j++)t[x]+=t[ch[x][j]];
}
}
void solve(){
RG int x=1,u,i;
while(K>0){
for(i=0;i<=25;i++){
if(!ch[x][i])continue;
u=ch[x][i];
if(t[u]>=K){
putchar(i+'a');
x=u;K-=size[x];break;
}
else K-=t[u];
}
}
}
void work()
{
scanf("%s%d%d",s+1,&T,&K);
n=strlen(s+1);
for(int i=1;i<=n;i++)build(s[i]-'a',i);
priwork();
if(t[1]<K){puts("-1");return ;}
solve();
}
int main()
{
work();
return 0;
}
bzoj 3998: [TJOI2015]弦论的更多相关文章
- BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2152 Solved: 716[Submit][Status] ...
- ●BZOJ 3998 [TJOI2015]弦论
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3998题解: 后缀自动机. 当T=0时, 由于在后缀自动机上沿着trans转移,每个串都是互不 ...
- BZOJ 3998: [TJOI2015]弦论 后缀自动机 后缀自动机求第k小子串
http://www.lydsy.com/JudgeOnline/problem.php?id=3998 后缀自动机应用的一个模板?需要对len进行一个排序之后再统计每个出现的数量,维护的是以该字符串 ...
- bzoj 3998 [TJOI2015]弦论——后缀自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3998 相同子串算多个的话,先求好 right ,然后求一个 sm 表示走到这个点之后有几种走 ...
- BZOJ 3998 TJOI2015 弦论 后缀自动机+DAG上的dp
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3998 题意概述:对于一个给定长度为N的字符串,求它的第K小子串是什么,T为0则表示不同位置 ...
- bzoj 3998: [TJOI2015]弦论【SA+二分||SAM】
SA的话t==0直接预处理出每个后缀的不同串贡献二分即可,然后t==1就按字典序枚举后缀,然后跳右端点计算和当前后缀的前缀相同的子串个数,直到第k个 不过bzoj上会T #include<ios ...
- BZOJ.3998.[TJOI2015]弦论(后缀自动机)
题目链接 \(Description\) 给定字符串S,求其第K小子串.(若T=0,不同位置的相同子串算1个:否则算作多个) \(Solution\) 建SAM,处理出对于每个节点,它和它的所有后继包 ...
- 【刷题】BZOJ 3998 [TJOI2015]弦论
Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...
- BZOJ 3998 [TJOI2015]弦论 ——后缀自动机
直接构建后缀自动机. 然后. 然后只需要再后缀自动机的go树上类似二分的方法进行查找即可,实际上是“26分”. 然后遇到了处理right集合的问题,然后觉得在go和parent树上上传都是可以的,毕竟 ...
随机推荐
- NO.7 项目需求分析
NO.7 项目需求分析 由于我们组的第一次选题并没有通过,所以我们又重新选择了一个题目--高校学生征信系统. 结合老师的作业要求,我们对该项目进行了详细的需求分析,软件需求规格说明书地址请点击这里.软 ...
- 201621123031 《Java程序设计》第1周学习总结
作业01-Java基本概念 1.本周学习总结 1.本周学习内容:Java发展史(简述).Java语言特点.JDK .JRE .JVM .Java的开发步骤.Java开发工具. 2.关键概念之间的联系: ...
- 第十二条:考虑实现Comparable接口
与前面讨论的方法不同,compareTo()方法并没有在Object类中定义.相反,它是Comparable接口中唯一的方法. 一个类的实例对象要想是可以比较大小的,那么这个类需要实现Comparab ...
- java的socket通信
本文讲解如何用java实现网络通信,是一个非常简单的例子,我比较喜欢能够立马看到结果,所以先上代码再讲解具体细节. 服务端: import java.io.BufferedReader; import ...
- HTML,文字两端对齐
text-align: justify样式的意思是文字两端对齐,但是有时候你会发现这东西不起左右,比如在div标签中的文字. 解决方法:在div中放一个空的span标签,并使用下面的样式. .just ...
- nyoj 黑色帽子
黑色帽子 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 最近发现了一个搞笑的游戏,不过目前还没玩过.一个舞会上,每个人头上都戴着一顶帽子,帽子只有黑 ...
- nat和napt技术
私网IP地址是指内部网络或主机的IP地址,公网IP地址是指在因特网上全球唯一的IP地址. RFC 1918为私有网络预留出了三个IP地址块,如下: A类:10.0.0.0-10.255.255.255 ...
- SiteMesh在项目中的配置
SiteMesh在项目中的配置 首先在web.xml里面增加siteMesh的配置: <filter> <filter-name>sitemesh</filter-nam ...
- Linux CentOS7.0 (03)安装验证 docker
一.安装docker 1.升级 Linux 的软件包和内核 sudo yum update 2.安装 docker (1) sudo yum install docker (2).验证docker安 ...
- docker生态系统
我的docker学习笔记6-docker生态 1.镜像即应用 代码构建.持续集成和持续交付 DaoCloud.Quay.IO 2.催生容器托管caas服务 基 ...