bzoj3998: [TJOI2015]弦论(SAM+dfs)
3998: [TJOI2015]弦论
题目:传送门
题解:
SAM的入门题目(很好的复习了SAM并加强Right集合的使用)
其实对于第K小的字符串直接从root开始一通DFS就好,因为son边是直接根据字符存的呀,相当于自带字典序,直接从‘a' 开始找。
一开始初始化一下从当前状态出发所能走的路径数(也就是能构成多少个字符串啦)
然后根据T= 0/1分情况来处理Right集合大小:
T== 0 :那Right集合大小就直接全部等于1咯
T== 1 : 直接累加啊(原始操作)
然后具体看代码注释吧:
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
struct SAM
{
int son[],fail,dep;
}ch[];int cnt,last,root,a[];
void add(int k)
{
int x=a[k];
int p=last,np=++cnt;ch[np].dep=k;
while(p && ch[p].son[x]==)ch[p].son[x]=np,p=ch[p].fail;
if(p==)ch[np].fail=root;
else
{
int q=ch[p].son[x];
if(ch[p].dep+==ch[q].dep)ch[np].fail=q;
else
{
int nq=++cnt;
ch[nq]=ch[q];ch[nq].dep=ch[p].dep+;
ch[np].fail=ch[q].fail=nq;
while(p && ch[p].son[x]==q)ch[p].son[x]=nq,p=ch[p].fail;
}
}
last=np;
}
int len,T,k,Rsort[],r[],sa[],sum[];
char s[];
void dfs(int x)
{
if(k<=r[x])return ;
k-=r[x];//要从x继续往下搜,那么结束位置为x的子串一定会更优,那就减去这样的子串个数啊,r记录的就是这个
for(int i=;i<=;i++)
if(ch[x].son[i]!=)
{
int y=ch[x].son[i];
if(k>sum[y])k-=sum[y];//当前k如果比y可以走出来的路径还要多,那么第k小的一定不在y的路径上。由于是按照字典序小到大问的,那么y的路径一定比后面枚举的要优,那也要减,sum记录的就是可行路径数
else {printf("%c",i+'a');dfs(y);return ;}
}
}
int main()
{
cnt=;root=last=++cnt;
scanf("%s",s+);len=strlen(s+);
for(int i=;i<=len;i++)a[i]=s[i]-'a';
for(int i=;i<=len;i++)add(i);
scanf("%d%d",&T,&k);
for(int i=;i<=cnt;i++)Rsort[ch[i].dep]++;
for(int i=;i<=len;i++)Rsort[i]+=Rsort[i-];
for(int i=cnt;i>=;i--)sa[Rsort[ch[i].dep]--]=i;
for(int i=,p=root;i<=len;i++)p=ch[p].son[a[i]],r[p]++;
for(int i=cnt;i>=;i--)
if(T==)r[ch[sa[i]].fail]=;
else r[ch[sa[i]].fail]+=r[sa[i]];
r[root]=;
for(int i=cnt;i>=;i--)
{
int now=sa[i];sum[now]=r[now];
for(int j=;j<=;j++)if(ch[now].son[j]!=)sum[now]+=sum[ch[now].son[j]];
}
if(k>sum[root])printf("-1\n");
else dfs(root);
return ;
}
bzoj3998: [TJOI2015]弦论(SAM+dfs)的更多相关文章
- BZOJ3998:[TJOI2015]弦论(SAM)
Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...
- [bzoj3998][TJOI2015]弦论_后缀自动机
弦论 bzoj-3998 TJOI-2015 题目大意:给定一个字符串,求其$k$小子串. 注释:$1\le length \le 5\cdot 10^5$,$1\le k\le 10^9$. 想法: ...
- 【BZOJ 3998】 3998: [TJOI2015]弦论 (SAM )
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2627 Solved: 881 Description 对于一 ...
- luogu P3975 [TJOI2015]弦论 SAM
luogu P3975 [TJOI2015]弦论 链接 bzoj 思路 建出sam. 子串算多个的,统计preant tree的子树大小,否则就是大小为1 然后再统计sam的节点能走到多少串. 然后就 ...
- [bzoj3998][TJOI2015]弦论-后缀自动机
Brief Description 给定一个字符串, 您需要求出他的严格k小子串或非严格k小子串. Algorithm Design 考察使用后缀自动机. 首先原串建SAM, 然后如果考察每个状态代表 ...
- bzoj3998 [TJOI2015]弦论(SAM)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3998 [题意] 询问排名第k的子串是谁,0代表相同子串不同位置算作相同,1代表相同子串 ...
- 【BZOJ3998】弦论 [SAM]
弦论 Time Limit: 10 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 对于一个给定长度为N的字符串,求它的第 ...
- BZOJ3998 TJOI2015弦论(后缀数组+二分答案)
先看t=1的情况.显然得求出SA(因为我不会SAM).我们一位位地确定答案.设填到了第len位,二分这一位填什么之后,在已经确定的答案所在的范围(SA上的某段区间)内二分,找到最后一个小于当前串的后缀 ...
- BZOJ3998 TJOI2015弦论(后缀自动机)
先考虑相同子串视为一个.按SAM的拓扑序预处理出从每个节点开始能得到多少个本质不同子串(注意虽然一个节点对应多个子串,但到达该点时当前的子串显然是确定为其中一个的),然后按位贪心即可. 相同子串视为多 ...
随机推荐
- 11g Rac PSU20180116手动补丁升级步骤
手动升级:软件包解压在新建的/home/grid/update 目录下ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1GRID_HOME=/u01 ...
- Windows显示我的电脑到桌面以及给一些程序设置快捷键
Windows显示我的电脑到桌面,我测试的是windows server 2012和windows10 1.按Win(键盘上的微软徽标键)+R,输入: rundll32.exe shell32.dl ...
- Nginx 配置埋点js日志采集
页面埋点&nginx日志采集 页面(web容器:httpd/nginx负载均衡 + apache server)<===> 日志采集服务器(nginx服务器) 通过某个页面跳转到我 ...
- Centos 6 搭建邮箱服务器教程
Centos 6 搭建邮箱服务器主要是是包括了Postfix, Dovecot和 MySQL了,下文我们详细的为各位介绍Centos 6 搭建邮箱服务器教程(Postfix, Dovecot和 MyS ...
- JavaScript函数传参
函数传参一: <html> <head> <meta charset="utf-8"> <title>无标题文档</title ...
- android黑科技系列——手机端破解神器MT的内购VIP功能破解教程
一.前言 在破解app的时候,我们现在几乎都是在PC端进行操作,但是之前bin神的MT管理器,可以在手机端直接破解,不过也有很大的局限性,但是对于一些简单的app破解没问题的.这个工具其实原理也很简单 ...
- 【Five-Minute Share】“请先了解所使用的工具 ,磨刀不误砍柴工”
数据是应用系统的血液,没有数据的系统应用价值是非常有限的.经过多年的观察发现,身边很多的程序开发人员在开发应用系统的时候,都是按照标准SQL语法及应用方法去进行数据库设计,并进行应用开发的,没有任何的 ...
- IE兼容opacity
filter:alpha(opacity=80); opacity: 0.57; /* Firefox, Safari(WebKit), Opera) filter: "alpha(opac ...
- Mysql 5.7 for windows 免安装版(解压版)安装和配置
网上写的不近详细,这里重新整理下. 准备: 1.windows操作系统 2.mysql 的解压版压缩文件 第一步: 解压mysql的压缩包到你的安装目录,因为是虚拟机,这里我就安装在C盘下:C:\my ...
- 解决python3在sublim Text3中中文乱码的问题
在Tool >> BulidingSystem 中 新建 python3 写入如下代码 { "cmd": ["C:/python3/python.exe&q ...