【BZOJ3998】[TJOI2015]弦论 后缀自动机
【BZOJ3998】[TJOI2015]弦论
Description
对于一个给定长度为N的字符串,求它的第K小子串是什么。
Input
第一行是一个仅由小写英文字母构成的字符串S
Output
输出仅一行,为一个数字串,为第K小的子串。如果子串数目不足K个,则输出-1
Sample Input
Sample Output
HINT
N<=5*10^5
题解:先跑后缀自动机,再处理出SAM的拓扑序,处理出在每个节点结束的子串个数,最后扫一遍SAM。如果在当前儿子的子树中结束的子串个数<k,那么k-=个数,再扫下一个儿子。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=1000010;
int n,T,K,last,tot;
int st[maxn],tb[maxn],pre[maxn],ch[maxn][26],dep[maxn],r[maxn],f[maxn];
char str[maxn];
void add(int x)
{
int p=last,np=++tot;
last=np,dep[np]=dep[p]+1;
for(;p&&!ch[p][x];p=pre[p]) ch[p][x]=np;
if(!p) pre[np]=1;
else
{
int q=ch[p][x];
if(dep[q]==dep[p]+1) pre[np]=q;
else
{
int nq=++tot;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
dep[nq]=dep[p]+1,pre[nq]=pre[q],pre[q]=pre[np]=nq;
for(;p&&ch[p][x]==q;p=pre[p]) ch[p][x]=nq;
}
}
}
int main()
{
last=tot=1;
scanf("%s%d%d",str,&T,&K),n=strlen(str);
int i,p,j;
for(i=1;i<=n;i++) add(str[i-1]-'a');
for(i=p=1;i<=n;i++) p=ch[p][str[i-1]-'a'],r[p]++;
for(i=1;i<=tot;i++) st[dep[i]]++;
for(i=1;i<=n;i++) st[i]+=st[i-1];
for(i=tot;i>=1;i--) tb[st[dep[i]]--]=i;
if(T) for(i=tot;i>=1;i--) r[pre[tb[i]]]+=r[tb[i]];
else for(i=1;i<=tot;i++) r[i]=1;
for(i=tot,r[1]=0;i>=1;i--) for(f[tb[i]]=r[tb[i]],j=0;j<26;j++) f[tb[i]]+=f[ch[tb[i]][j]];
if(f[1]<K)
{
printf("-1");
return 0;
}
p=1;
while(K>r[p])
{
for(i=0,K-=r[p];i<26&&K>f[ch[p][i]];i++) K-=f[ch[p][i]];
printf("%c",'a'+i),p=ch[p][i];
}
return 0;
}
【BZOJ3998】[TJOI2015]弦论 后缀自动机的更多相关文章
- [bzoj3998][TJOI2015]弦论-后缀自动机
Brief Description 给定一个字符串, 您需要求出他的严格k小子串或非严格k小子串. Algorithm Design 考察使用后缀自动机. 首先原串建SAM, 然后如果考察每个状态代表 ...
- 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp
题目描述 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...
- 【BZOJ-3998】弦论 后缀自动机
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2018 Solved: 662[Submit][Status] ...
- BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2152 Solved: 716[Submit][Status] ...
- BZOJ 3998: [TJOI2015]弦论 后缀自动机 后缀自动机求第k小子串
http://www.lydsy.com/JudgeOnline/problem.php?id=3998 后缀自动机应用的一个模板?需要对len进行一个排序之后再统计每个出现的数量,维护的是以该字符串 ...
- BZOJ 3998 TJOI2015 弦论 后缀自动机+DAG上的dp
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3998 题意概述:对于一个给定长度为N的字符串,求它的第K小子串是什么,T为0则表示不同位置 ...
- BZOJ 3998 [TJOI2015]弦论 ——后缀自动机
直接构建后缀自动机. 然后. 然后只需要再后缀自动机的go树上类似二分的方法进行查找即可,实际上是“26分”. 然后遇到了处理right集合的问题,然后觉得在go和parent树上上传都是可以的,毕竟 ...
- [TJOI2015]弦论(后缀自动机)
/* 一道在树上乱搞的题目 建立出parent树来, 然后就能搞出每个节点往后能扩展出几个串, 至于位置不同算同一个的话就强制让right集合大小为1即可 然后在树上类比权值线段树找第k大26分统计一 ...
- BZOJ.3998.[TJOI2015]弦论(后缀自动机)
题目链接 \(Description\) 给定字符串S,求其第K小子串.(若T=0,不同位置的相同子串算1个:否则算作多个) \(Solution\) 建SAM,处理出对于每个节点,它和它的所有后继包 ...
随机推荐
- TestNG+Maven+IDEA环境搭建
TestNG+Maven+IDEA环境搭建 前言: 主要进行TestNG测试环境的搭建 所需环境: 1.IDEA UItimate 2.JDK 3.Maven 一.创建工程 File –>new ...
- REDIS 内存满时删除策略
REDIS 内存满时删除策略
- mysqli 预处理语句
预处理语句用于执行多个相同的 SQL 语句,并且执行效率更高. <?php // 设置编码格式 header('content-type:text/html;charset=utf-8'); / ...
- HDU 5094 --Maze【BFS && 状态压缩】
Maze Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Others) Total Sub ...
- selenium从入门到应用 - 8,selenium+testNG实现多线程的并发测试
本系列所有代码 https://github.com/zhangting85/simpleWebtest本文将介绍一个Java+TestNG+Maven+Selenium的web自动化测试脚本环境下s ...
- selenium从入门到应用 - 5,页面对象设计模式下的页面模块
本系列所有代码 https://github.com/zhangting85/simpleWebtest 本文将介绍一个Java+TestNG+Maven+Selenium的web自动化测试脚本环境下 ...
- Phalcon 訪问控制列表 ACL(Access Control Lists ACL)
Phalcon在权限方面通过 Phalcon\Acl 提供了一个轻量级的 ACL(訪问控制列表). Access Control Lists (ACL) 同意系统对用户的訪问权限进行控制,比方同意訪问 ...
- 服务器上使用matplotlib.pyplot绘图
在linux服务器端执行python脚本,有时候需要画图,但是linux没有GUI界面,因此需要在导入matplotlib.pyplot库之前先执行 import matplotlib as mpl ...
- mysql group by 与order by的实例分析(mysql分组统计后最大值)
CREATE TABLE `test` ( `id` ) NOT NULL AUTO_INCREMENT, `name` ) CHARACTER SET latin1 DEFAULT NULL, `c ...
- linux-centos7中lnmp服务器编译安装含systemctl启动service(转)
centos7 nginx mysql php 可以分开安装 然后在配置nginx互php的 先安装一些必要的库 ---------------------------------------- ...