Description

对于一个给定长度为N的字符串,求它的第K小子串是什么。

Input

第一行是一个仅由小写英文字母构成的字符串S

第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个。T=1则表示不同位置的相同子串算作多个。K的意义如题所述。

Output

输出仅一行,为一个数字串,为第K小的子串。如果子串数目不足K个,则输出-1

Sample Input

aabc
0 3

Sample Output

aab

解题思路:

在后缀自动机Parent树上的每个节点所代表的串都是以祖先节点为后缀的逆序子串。

利用这一性质我们可以很方便地求解一个子串出现多少次的问题(其子树内实点数)

那么这道题是求解排名的问题。

一个后缀自动机可以识别一个串所有后缀。

若按前缀查询,就是所有字串,字串出现次数和就是其母串次数和的累加。

t=0 时,认为其实点只有自己记录。

而 t=1时,认为其子节点被记录。

累加其sum值作为以此值为前缀的串个数。

最后相减逼近答案输出即可。

代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long lnt;
struct sant{
int tranc[];
int len;
int pre;
}s[];
struct pnt{
lnt sum;
lnt size;
}p[];
int siz;
int fin;
int n,t;
lnt k;
char tmp[];
int has[];
int topo[];
void Insert(int c)
{
int nwp,nwq,lsp,lsq;
nwp=++siz;
s[nwp].len=s[fin].len+;
p[nwp].size=;
for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre)
s[lsp].tranc[c]=nwp;
if(!s[lsp].tranc[c])
s[nwp].pre=;
else{
lsq=s[lsp].tranc[c];
if(s[lsq].len==s[lsp].len+)
s[nwp].pre=lsq;
else{
nwq=++siz;
s[nwq]=s[lsq];
s[nwq].len=s[lsp].len+;
s[nwp].pre=s[lsq].pre=nwq;
while(s[lsp].tranc[c]==lsq)
{
s[lsp].tranc[c]=nwq;
lsp=s[lsp].pre;
}
}
}
fin=nwp;
return ;
}
int main()
{
fin=siz=;
scanf("%s",tmp+);
scanf("%d%lld",&t,&k);
n=strlen(tmp+);
for(int i=;i<=n;i++)
Insert(tmp[i]-'a');
for(int i=;i<=siz;i++)
has[s[i].len]++;
for(int i=;i<=siz;i++)
has[i]+=has[i-];
for(int i=;i<=siz;i++)
topo[has[s[i].len]--]=i;
for(int i=siz;i;i--)
if(t)
p[s[topo[i]].pre].size+=p[topo[i]].size;
else
p[topo[i]].size=;
p[].size=;
for(int i=siz;i;i--)
{
int h=topo[i];
p[h].sum=p[h].size;
for(int c=;c<;c++)
if(s[h].tranc[c])
p[h].sum+=p[s[h].tranc[c]].sum;
}
if(k>p[].sum)
{
puts("-1");
return ;
}
int root=;
while(k>)
{
for(int c=;c<;c++)
{
int l=s[root].tranc[c];
if(!l)continue;
if(k>p[l].sum)
k-=p[l].sum;
else{
putchar('a'+c);
root=s[root].tranc[c];
k-=p[root].size;
break;
}
}
}
return ;
}
 

BZOJ3998: [TJOI2015]弦论(后缀自动机,Parent树)的更多相关文章

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

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

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

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

  3. 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp

    题目描述 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...

  4. 【BZOJ-3998】弦论 后缀自动机

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

  5. [十二省联考2019]字符串问题——后缀自动机+parent树优化建图+拓扑序DP+倍增

    题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的 ...

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

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

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

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

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

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

  9. [TJOI2015]弦论(后缀自动机)

    /* 一道在树上乱搞的题目 建立出parent树来, 然后就能搞出每个节点往后能扩展出几个串, 至于位置不同算同一个的话就强制让right集合大小为1即可 然后在树上类比权值线段树找第k大26分统计一 ...

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

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

随机推荐

  1. CKEditor高级编辑器

    是否感觉后台分类描写叙述信息.商品描写叙述信息以及文章描写叙述信息 编写时很的不方便?有时候会将word的格式也复制过来了?那这个插件就比較适合了. 本插件使用CKEditor最新版本号,复制过来的内 ...

  2. HotSpotVM的Java堆实现浅析#1:初始化

    今天来看看HotSpotVM的Java堆初始化. Universe Java堆的初始化主要由Universe模块来完毕,来看下Universe模块初始化的代码,universe_init. jint ...

  3. 美团实习生电面之谈(成功拿到offer)

    3月底进行了美团的一次实习生面试(Java研发project师).当时顺利的通过一面.以下是我的一面: 1.CPU由哪些部分组成 2.线程和进程的差别 3.Java类载入机制 4.怎样实现一个字符串的 ...

  4. 理解Linq查询

    using System; using System.Linq; static class Program { static double Square(double n) { Console.Wri ...

  5. visual studio 添加库文件

    我在visual studio中使用OpenGL时需要添加额外的库 一 首先下载库文件,里面将会有一些.h文件和.lib文件,打开visual studio安装目录下打开: D:\program\VS ...

  6. Scrapy中将数据保存至数据库

    一.在settings.py文件中配置数据库连接参数 # 数据库连接参数 DB_HOST = '192.168.183.1' DB_PORT = 3306 DB_USER = 'root' DB_PA ...

  7. 【Uva 307】Sticks

    [Link]: [Description] 给你最多n个棍子; (n< = 64) 每根棍子长度(1..50) 问你这n根棍子,可以是由多少根长度为x的棍子分割出来的; x要求最小 [Solut ...

  8. 编译安装 gcc 4.9并验证使用

    编译安装 gcc 4.9并验证使用 1. 准备环境(GCC 编译器) centOS 6.3 cat /proc/version Linux version 2.6.32-279.el6.x86_64 ...

  9. 怎样借助log4j把日志写入数据库中

            log4j是一个优秀的开源日志记录项目.我们不仅能够对输出的日志的格式自定义,还能够自定义日志输出的目的地,比方:屏幕.文本文件,数据 库,甚至能通过socket输出.本节使用MySQ ...

  10. Python 值传递和引用传递

    值传递和引用传递 參考地址:http://www.dataguru.cn/thread-489552-1-1.html python的值传递不会改变传入參数的值,而引用传递传入的是一个地址.有点相似c ...