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树上上传都是可以的,毕竟 ...
随机推荐
- prototype 原型链
// 方法1 var aa=function(){ function bb(){ this.name="1111"; console.log(this.name) }; bb.pr ...
- TOTP算法 基于时间的一次性密码
/** Copyright (c) 2011 IETF Trust and the persons identified as authors of the code. All rights rese ...
- Hibernate之Hibernate的体系结构
体系结构简图: 这是一张体系结构的简图,其中的hibernate.properties文件的作用相当于配置文件hibernate.cfg.xml XML Mapping对应的就是映射文件 XXXX.h ...
- 20165230 2017-2018-2 《Java程序设计》第4周学习总结
20165230 2017-2018-2 <Java程序设计>第4周学习总结 教材学习内容总结 子类与继承 通过class 子类名 extends 父类名定义子类.子类只能继承一个父类,关 ...
- python中的赋值与深浅拷贝
Python当中对于拷贝,分为两种类型.一种是数字和字符串,另一种就是列表.元组.字典等其他类型了. 一.数字和字符串的拷贝 1.赋值 举个栗子: a1 = 123123 a2 = 123123 # ...
- SpringBoot入门:新一代Java模板引擎Thymeleaf(理论)
Spring Boot 提供了spring-boot-starter-web来为Web开发予以支持,spring-boot-starter-web为我们提供了嵌入的Tomcat以及SpringMVC的 ...
- Django Form组件 学生管理系统
from django.db import models # Create your models here. class Classes(models.Model): title=models.Ch ...
- DataContractJsonSerializer序列化时间类型时转换为UTC溢出问题
问题描述 如下一个实体类,含有非空时间类型属性,默认是C#的最小时间,在使用DataContractJsonSerializer将该类对象序列化成JSON时,抛出异常信息:System.Runtime ...
- STM32-正弦波可调(50HZ~20KHZ可调、峰峰值0~3.3V可调)
1.原理: 通过定时器每隔一段时间触发一次DAC转换,然后通过DMA发送正玄波码表值给DAC. 当需要改变频率HZ时,只需要修改定时器频率即可(最高只能达到20KHz) 当需要改变正玄波的正峰峰值/负 ...
- 部署testlink报错,安装wampserver时提示丢失MSVCR110.dll
安装wampserver时提示丢失MSVCR110.dll(在windows server上可用)对于32位系统,安装Wampserver 后启动的时候提示系统错误:MSVCR110.dll丢失.于是 ...