BZOJ 3998: [TJOI2015]弦论 后缀自动机 后缀自动机求第k小子串
http://www.lydsy.com/JudgeOnline/problem.php?id=3998
后缀自动机应用的一个模板?需要对len进行一个排序之后再统计每个出现的数量,维护的是以该字符串为前缀的字符串数量和某字符串的出现数量。
wa了两次,写题时犯得错误有:
1.使用样例检查出来向下搜索字符串时没有减去字符串本身出现的数量,比如样例中aabc 0 3,不计重复的情况下向下搜索还要多减一下a和aa分别出现的1次;
2.第一次wa检查出来val没有在建自动机的时候赋值,所以T=1的时候val和g都=0;
3.第二次wa检查半天自己随便打了个字符串跑一下发现数量不对,然后找了半天最后看出来是自己的ac自动机写错了一个len的赋值,太zz了orz。
还是要熟悉一下自动机的写法。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int maxn=;
int siz,T;
long long K;
char ch[maxn*]={};
int cnt[maxn*]={};//按照深度排序
int b[maxn*]={};//排序后每个的rk
long long val[maxn*]={};//每个状态出现的数目
long long g[maxn*]={};//每个状态及其所有以其为前缀后继的数目
struct nod{
int sig[];
int f,len;
void cle(){f=-;len=;memset(sig,-,sizeof(sig));}
}t[maxn*];
int las=,tot=;
void add(int z){
int x=++tot; t[x].cle();
t[x].len=t[las].len+;
val[x]=;
int i=las;
for(;i!=-&&t[i].sig[z]==-;i=t[i].f)
t[i].sig[z]=x;
if(i==-)t[x].f=;
else{
int p=t[i].sig[z];
if(t[p].len==t[i].len+)t[x].f=p;
else{
int y=++tot;t[y].cle();
t[y]=t[p];
t[y].len=t[i].len+;
t[x].f=t[p].f=y;
for(;i!=-&&t[i].sig[z]==p;i=t[i].f)
t[i].sig[z]=y;
}
}las=x;
}
void pai(){
for(int i=;i<=tot;i++)++cnt[t[i].len];
for(int i=;i<=siz;i++)if(i)cnt[i]+=cnt[i-];
for(int i=;i<=tot;i++)b[cnt[t[i].len]--]=i;
}
void doit(){
for(int i=tot+;i;i--){
int z=b[i];
if(T&&z)val[t[z].f]+=val[z];
else val[z]=;
}
val[]=;
for(int i=tot+;i;i--){
int z=b[i];
g[z]=val[z];
for(int j=;j<;j++)if(t[z].sig[j]!=-)g[z]+=g[t[z].sig[j]];
}
}
void getit(int x,long long k){
if(k<)return;
long long sum=;
for(int i=;i<;i++){
if(!t[x].sig[i])continue;
if(sum<k&&sum+g[t[x].sig[i]]>=k){
printf("%c",'a'+i);
getit(t[x].sig[i],k-sum-val[t[x].sig[i]]);
break;
}sum+=g[t[x].sig[i]];
}
}
int main(){
t[].cle();
scanf("%s",ch);siz=strlen(ch);
for(int i=;i<siz;i++)add(int(ch[i]-'a'));
pai();
scanf("%d%lld",&T,&K);
doit();
if(K>g[])printf("-1\n");
else getit(,(long long)K);
return ;
}
BZOJ 3998: [TJOI2015]弦论 后缀自动机 后缀自动机求第k小子串的更多相关文章
- BZOJ 3998 TJOI2015 弦论 后缀自动机+DAG上的dp
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3998 题意概述:对于一个给定长度为N的字符串,求它的第K小子串是什么,T为0则表示不同位置 ...
- BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2152 Solved: 716[Submit][Status] ...
- BZOJ 3998 [TJOI2015]弦论 ——后缀自动机
直接构建后缀自动机. 然后. 然后只需要再后缀自动机的go树上类似二分的方法进行查找即可,实际上是“26分”. 然后遇到了处理right集合的问题,然后觉得在go和parent树上上传都是可以的,毕竟 ...
- bzoj 3998 [TJOI2015]弦论——后缀自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3998 相同子串算多个的话,先求好 right ,然后求一个 sm 表示走到这个点之后有几种走 ...
- BZOJ.3998.[TJOI2015]弦论(后缀自动机)
题目链接 \(Description\) 给定字符串S,求其第K小子串.(若T=0,不同位置的相同子串算1个:否则算作多个) \(Solution\) 建SAM,处理出对于每个节点,它和它的所有后继包 ...
- BZOJ 3998: [TJOI2015]弦论(后缀自动机)
传送门 解题思路 \(T=0\)时就和SP7258一样,\(T=1\)时其实也差不多,只不过要把每个点原来是\(1\)的权值改为\(Right\)集合的大小. 代码 #include<iostr ...
- ●BZOJ 3998 [TJOI2015]弦论
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3998题解: 后缀自动机. 当T=0时, 由于在后缀自动机上沿着trans转移,每个串都是互不 ...
- bzoj 3998: [TJOI2015]弦论【SA+二分||SAM】
SA的话t==0直接预处理出每个后缀的不同串贡献二分即可,然后t==1就按字典序枚举后缀,然后跳右端点计算和当前后缀的前缀相同的子串个数,直到第k个 不过bzoj上会T #include<ios ...
- bzoj 3998: [TJOI2015]弦论
Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...
随机推荐
- 【CodeForces】790 C. Bear and Company 动态规划
[题目]C. Bear and Company [题意]给定大写字母字符串,交换相邻字符代价为1,求最小代价使得字符串不含"VK"子串.n<=75. [算法]动态规划 [题解 ...
- 爬虫实战--基于requests和beautifulsoup的妹子网图片爬取(福利哦!)
#coding=utf-8 import requests from bs4 import BeautifulSoup import os all_url = 'http://www.mzitu.co ...
- Verilog笔记.1.基本语法
0.前 抽象模型分级: • 系统级(system):用高级语言结构实现设计模块的外部性能的模型.• 算法级(algorithm):用高级语言结构实现设计算法的模型.• RTL级(Register Tr ...
- thinkphp 漂亮的分页样式
---恢复内容开始--- 首先:需要两个文件 page.class.php page.css 1.在TP原有的 page.class.php 文件稍作修改几条代码就可以了, 修改过的地方我会注释, 2 ...
- mysql数据库单表增删改查命令
数据库DB-database-mysql 课程安排 第一天: 1.数据库定义以及设计 2.mysql服务端的安装 3.mysql-dos操作 库的操作 表的操作 4.mysql客户端navicate工 ...
- 安全测试===CSRF攻击简介
http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html
- Linux 用户态与内核态的交互【转载】
Linux 用户态与内核态的交互 在 Linux 2.4 版以后版本的内核中,几乎全部的中断过程与用户态进程的通信都是使用 netlink 套接字实现的,例如iprote2网络管理工具,它与内核的交 ...
- INIT_WORK
借助runtime pm,在需要使用模块时,增加引用计数(可调用pm_runtime_get),不需要使用时,减少引用计数(可调用pm_runtime_put). 1.INIT_WORK(struct ...
- c#操作pdf文件系列之创建文件
1.我使用的工具是vs2013,引用的第三方程序集itextpdf 具体安装方法,可以通过nuget搜索iTextSharp然后进行安装. 2具体代码如下 创建两个不同pdf文件,每个地方什么意思代码 ...
- IP负载均衡技术
参考链接:http://www.360doc.com/content/12/1117/19/820209_248442094.shtml