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

Input

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

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

Output

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

Sample Input

aabc
0 3

Sample Output

aab

Hint

\(N<=5*10^5\)

\(T<2\)

\(K<=1e9\)

题意:

中文题面,不解释。

题解:

把串放进后缀自动机,然后处理一遍,如果\(T=0\),则所有点权为1;否则,把每个点的\(parent\)加上当前\(size\)。然后反向拓扑,像求第\(k\)大子串如这个一样求就行了。

#include<bits/stdc++.h>
using namespace std;
const int N=1000010;
char s[N];
int a[N],c[N];
void cmax(int &a,int b){
a=max(a,b);
}
void cmin(int &a,int b){
a=min(a,b);
}
struct SAM{
int last,cnt;
int size[N],ch[N][26],fa[N<<1],l[N<<1],sum[N];
void ins(int c){
int p=last,np=++cnt;last=np;l[np]=l[p]+1;
for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
if(!p)fa[np]=1;
else{
int q=ch[p][c];
if(l[p]+1==l[q])fa[np]=q;
else{
int nq=++cnt;l[nq]=l[p]+1;
memcpy(ch[nq],ch[q],sizeof ch[q]);
fa[nq]=fa[q];fa[q]=fa[np]=nq;
for(;ch[p][c]==q;p=fa[p])ch[p][c]=nq;
}
}
size[np]=1;
}
void build(char s[]){
int len=strlen(s+1);
last=cnt=1;
for(int i=1;i<=len;++i)ins(s[i]-'a');
}
void calc(int op){
memset(c,0,sizeof c);
for(int i=1;i<=cnt;++i)c[l[i]]++;
for(int i=1;i<=cnt;++i)c[i]+=c[i-1];
for(int i=1;i<=cnt;++i)a[c[l[i]]--]=i;
for(int i=cnt;i;--i){
int p=a[i],f=fa[p];
if(op){
size[f]+=size[p];
}else{
size[p]=1;
}
}
size[1]=0;
for(int i=cnt;i;--i){
int p=a[i];
sum[p]=size[p];
for(int j=0;j<26;++j){
if(ch[p][j])sum[p]+=sum[ch[p][j]];
}
}
}
void find(int k){
int p=1;
size[0]=0;
while(k){
int a=0;
while(k>sum[ch[p][a]]&&a<26){
if (ch[p][a]) k-=sum[ch[p][a]];
a++;
}
if(a>=26){
puts("-1");
return;
}
putchar('a'+a);k-=size[ch[p][a]];
if(k<=0)return;
p=ch[p][a];
}
}
}sam;
int main(){
cin>>s+1;
sam.build(s);
int t,k;
cin>>t>>k;
sam.calc(t);
sam.find(k);
}

弦论(tjoi2015,bzoj3998)(sam(后缀自动机))的更多相关文章

  1. Distinct Substrings(spoj694)(sam(后缀自动机)||sa(后缀数组))

    Given a string, we need to find the total number of its distinct substrings. Input \(T-\) number of ...

  2. LCS2 - Longest Common Substring II(spoj1812)(sam(后缀自动机)+多串LCS)

    A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\ ...

  3. LCS - Longest Common Substring(spoj1811) (sam(后缀自动机)+LCS)

    A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\ ...

  4. Lexicographical Substring Search (spoj7259) (sam(后缀自动机)+第k小子串)

    Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...

  5. Substrings(SPOJ8222) (sam(后缀自动机))

    You are given a string \(S\) which consists of 250000 lowercase latin letters at most. We define \(F ...

  6. sam(后缀自动机)

    后缀自动机ins解释 void ins(int c){ int p=last;//将当前节点的parent节点变为last int np=++cnt;//建立新节点 last=np;//将last设为 ...

  7. Luogu P3346 [ZJOI2015]诸神眷顾的幻想乡 广义SAM 后缀自动机

    题目链接 \(Click\) \(Here\) 真的是好题啊-不过在说做法之前先强调几个自己总是掉的坑点. 更新节点永远记不住往上跳\(p = fa[p]\) 新建节点永远记不住\(len[y] = ...

  8. 字符串(tjoi2016,heoi2016,bzoj4556)(sam(后缀自动机)+线段树合并+倍增+二分答案)

    佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了 一个长为\(n\)的字符串\(s\),和\(m\)个问题.佳媛姐姐必须正确回答这\(m\)个问题, ...

  9. 后缀自动机SAM学习笔记

    前言(2019.1.6) 已经是二周目了呢... 之前还是有一些东西没有理解到位 重新写一下吧 后缀自动机的一些基本概念 参考资料和例子 from hihocoder DZYO神仙翻译的神仙论文 简而 ...

随机推荐

  1. struts框架问题五之向值栈中保存数据

    5. 问题五: 向值栈保存数据 (主要针对root栈) > valueStack.push(Object obj); * push方法的底层调用root对象的push方法(把元素添加到0位置) ...

  2. 怎样完整地离线更新并升级基于 Debian 的操作系统

    不久之前我已经向你展示了如何在任意离线的 Ubuntu 和 Arch Linux 操作系统上安装软件. 今天,我们将会看看如何完整地离线更新并升级基于 Debian 的操作系统. 和之前所述方法的不同 ...

  3. 【Web】网站主如何更改网页标签的图标(favicon.ico)

    修改web项目的favicon图标,方式有两种:全局方式和局部方式 全局方式: 进入服务器\webapps\ROOT,然后用自己的favicon.ico替换服务器自带的favicon.ico图片 局部 ...

  4. java--多线程编程简介

    1.什么时候使用多线程编程 一个任务在正常情况下是按顺序执行的,但是如果当前任务里有多个相似进程块(例如for,while语句),我们就可以考虑把这些代码块抽出来并行运行,无需阻塞 2.实现多线程的几 ...

  5. 《Linux多线程编程手册》读书笔记

    第二章 基本线程编程 1.(P25)如果多个线程等待同一个线程终止,则所有等待线程将一直等到目标线程终止.然后,一个等待线程成功返回,其余的等待线程将失败并返回ESRCH错误. 2.(P26)将新线程 ...

  6. py-函数进阶

    名称空间 又名name space, 顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方 名称空间共3种, ...

  7. HDU 1718 Rank (排序)

    题意:给你n个学号和成绩,并且给定一个学号,让找这个学号是多少名. 析:用个结构体,按成绩排序,然后找那个学号,这个题有一个小坑,那就是并列的情况, 可能并列多少名,这个要考虑一下,其他的easy! ...

  8. Vivado 常见报错

    1.[Synth 8-2543] port connections cannot be mixed ordered and named 说明例化时最后一个信号添加了一个逗号. 2. 原因:报告说明有一 ...

  9. [转]谈谈 Mifare Classic 破解

    Mifare Classic 提供 1 Kb - 4Kb 的容量,现在国内采用的多数是 Mifare Classic 1k(S50)[后面简称 M1 卡] M1 卡有从 0 到 15 共 16 个扇区 ...

  10. Shell编程-06-Shell中的if语句

    目录 基本语法 if示例     在任何一门语言中,判断语句总是少不了,今天来学习一下Shell中的if语句. 基本语法 单分支情况 第一种语法 if <条件表达式> then 语句 fi ...