题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3998

相同子串算多个的话,先求好 right ,然后求一个 sm 表示走到这个点之后有几种走法,即把 DAG 上自己能走到的点的 right 都收集起来,可用拓扑序解决。

相同子串算一个的话,给 DAG 上每个节点都赋上一个1,表示走到那个节点的话算一个子串;然后把 DAG 上自己能走到的点的1都收集起来。

然后可按字典序 dfs 这个 DAG ,如果 k 在这个分支里的话就走进去,否则 k -= sm[ ] ,然后看别的分支。

不用管 len[ ] ,因为 len[ ] 表示自己这个点管辖的许多子串,但如果自己是 dfs 地走过来,就只对应了其中一个子串,所以只用管 right 就行了。

之所以相同子串算一个的话要给复制出来的那些 nq 也赋一个1,是因为 nq 只是分了一些 q 管辖的子串;如果自己 dfs 着本应走到 q 点,但因为 nq 分管了一些而走到了 nq 点的话,自己也算走到了一个子串结尾的位置(1个而不是len个),所以应该计数1。

注意用 a[ i ] 而不是 i 。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=5e5+,M=1e6+,K=;
int lst=,cnt=,go[M][K],fa[M],l[M],rt[M];ll sm[M];
int tx[N],a[M];
char ch[N];
void add(int w)
{
int p=lst,np=++cnt;lst=np;l[np]=l[p]+;rt[np]=;
for(;p&&!go[p][w];p=fa[p])go[p][w]=np;
if(!p)fa[np]=;
else
{
int q=go[p][w];
if(l[q]==l[p]+)fa[np]=q;
else
{
int nq=++cnt;l[nq]=l[p]+;
fa[nq]=fa[q];fa[q]=nq;fa[np]=nq;
memcpy(go[nq],go[q],sizeof go[q]);
for(;go[p][w]==q;p=fa[p])go[p][w]=nq;
}
}
}
void Rsort(int n,bool T)
{
for(int i=;i<=cnt;i++)tx[l[i]]++;
for(int i=n-;i>=;i--)tx[i]+=tx[i+];
for(int i=cnt;i;i--)a[tx[l[i]]--]=i;
for(int i=;i<=cnt;i++)
{
int d=a[i];
if(!T)rt[d]=;
else rt[fa[d]]+=rt[d];
}
// if(T)for(int i=1;i<=cnt;i++)rt[fa[a[i]]]+=rt[a[i]];//if()!!!!///a[]!!!!!!
for(int i=;i<=cnt;i++)
{
int d=a[i];///
sm[d]=rt[d];
for(int j=;j<=;j++)
if(go[d][j])
{
sm[d]+=sm[go[d][j]];
}
}
rt[]=;//
}
int main()
{
scanf("%s",ch);int n=strlen(ch);
for(int i=;i<n;i++)add(ch[i]-'a'+);
int T,k; scanf("%d%d",&T,&k);
Rsort(n,T);
int cr=;
bool flag=;
while()
{
if(rt[cr]>=k)break;
k-=rt[cr]; int ycr=cr;
for(int i=,d;i<=;i++)
if(sm[d=go[cr][i]]>=k)
{putchar(i+'a'-);cr=d;break;}
else k-=sm[d];
if(cr==ycr){printf("-1");break;}
}
return puts("");
}

bzoj 3998 [TJOI2015]弦论——后缀自动机的更多相关文章

  1. BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]

    3998: [TJOI2015]弦论 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2152  Solved: 716[Submit][Status] ...

  2. BZOJ 3998: [TJOI2015]弦论 后缀自动机 后缀自动机求第k小子串

    http://www.lydsy.com/JudgeOnline/problem.php?id=3998 后缀自动机应用的一个模板?需要对len进行一个排序之后再统计每个出现的数量,维护的是以该字符串 ...

  3. BZOJ 3998 TJOI2015 弦论 后缀自动机+DAG上的dp

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3998 题意概述:对于一个给定长度为N的字符串,求它的第K小子串是什么,T为0则表示不同位置 ...

  4. BZOJ 3998 [TJOI2015]弦论 ——后缀自动机

    直接构建后缀自动机. 然后. 然后只需要再后缀自动机的go树上类似二分的方法进行查找即可,实际上是“26分”. 然后遇到了处理right集合的问题,然后觉得在go和parent树上上传都是可以的,毕竟 ...

  5. BZOJ.3998.[TJOI2015]弦论(后缀自动机)

    题目链接 \(Description\) 给定字符串S,求其第K小子串.(若T=0,不同位置的相同子串算1个:否则算作多个) \(Solution\) 建SAM,处理出对于每个节点,它和它的所有后继包 ...

  6. BZOJ 3998: [TJOI2015]弦论(后缀自动机)

    传送门 解题思路 \(T=0\)时就和SP7258一样,\(T=1\)时其实也差不多,只不过要把每个点原来是\(1\)的权值改为\(Right\)集合的大小. 代码 #include<iostr ...

  7. ●BZOJ 3998 [TJOI2015]弦论

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3998题解: 后缀自动机. 当T=0时, 由于在后缀自动机上沿着trans转移,每个串都是互不 ...

  8. 【BZOJ3998】[TJOI2015]弦论 后缀自动机

    [BZOJ3998][TJOI2015]弦论 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T ...

  9. [bzoj3998][TJOI2015]弦论-后缀自动机

    Brief Description 给定一个字符串, 您需要求出他的严格k小子串或非严格k小子串. Algorithm Design 考察使用后缀自动机. 首先原串建SAM, 然后如果考察每个状态代表 ...

随机推荐

  1. COS-5资源分配与调度

    操作系统是用户和计算机的接口,同时也是计算机硬件和其他软件的接口.操作系统的功能包括管理计算机系统的硬件.软件及数据资源,控制程序运行,改善人机界面,为其它应用软件提供支持,让计算机系统所有资源最大限 ...

  2. Spring Cloud 微服务开放平台接口

    github源码地址:https://github.com/spring-cloud/spring-cloud-security 前言: 什么是开放平台接口 场景 : 总公司与子公司 对接接口  还有 ...

  3. spark 写hbase

    部分情况下: saveAsNewAPIHadoopDataset不能用 大坑, org.apache.hadoop.mapred 和 org.apache.hadoop.mapreduce两个包的混乱 ...

  4. eclipse中设置新建jsp文件的编码格式

    每次新建jsp文件时,默认都是ISO-8859-1,每次涉及有中文的时候都得改成UTF-8,这就很麻烦了. 解决的方法就是,设置新建jsp文件的编码格式. 解决方法 结果 或者更改它的encoding

  5. eclipse中使用adb连接小米2调试程序的问题.

    http://jingyan.baidu.com/article/8065f87fcbec19233124983e.html eclipse连接小米2调试程序的问题. | 浏览:5494 | 更新:2 ...

  6. DPDK在OpenStack中的实现

    随着云计算与大数据的快速发展,其对数据中心网络的性能和管理提出了更高的要求,但传统云计算架构存在多个I/O瓶颈,由于云平台基本上是采用传统的X86服务器加上虚拟化方式组建,随着40G.100G高速网卡 ...

  7. tensorflow笔记:模型的保存与训练过程可视化

    tensorflow笔记系列: (一) tensorflow笔记:流程,概念和简单代码注释 (二) tensorflow笔记:多层CNN代码分析 (三) tensorflow笔记:多层LSTM代码分析 ...

  8. Python — List、Set、Tuple、Dictionary之间的区别、参数传递

    1.list 列表 有序集合,随时增删.包含的数据类型可以不同:整数.浮点数.字符串.list.tuple.dict.set.bool.空值.常量. list = [12, 'Yummy', 19.2 ...

  9. Ceph:pg peering过程分析

    转自:https://www.ustack.com/blog/ceph%ef%bc%8dpg-peering/ Peering:互为副本的三个(此处为设置的副本个数,通常设置为3)pg的元数据达到一致 ...

  10. null与""的区别

    两者的区别与 “数字0和没有不是同一种概念”是一个道理.null是空对象,""是空字符串null可以赋值给任何对象,而""就不行了,只能赋值给字符串对象如:St ...