BZOJ3998 弦论



给一个字符串,问其第\(K\)小字串是什么

两种形式

1.不同起始位置的相同串只算一次

2.不同起始位置的相同串各算一次

首先建\(SAM\)

所有串的数量就是\(SAM\)中的从起始点开始的路径数量,所以可以先在\(SAM\)上\(dp\)出来从所有节点开始的子串数量,然后递归找就好了

\(dp\)的转移为\(dp[u] = cnt[u] + \sum_{v \in children} dp[v]\)

对于第一种,每个节点的\(cnt\)为\(1\),对于第二种形式,每个节点的\(cnt\)为其\(right\)集合的大小

所以第二种情况下要计算出每个状态的\(right\)集合的大小

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6+7;
typedef long long int LL;
char s[MAXN];
int t,K,n;
struct SAM{
int link[MAXN],len[MAXN],ch[MAXN][26],last,tot;
LL f[MAXN],cnt[MAXN];
vector<int> G[MAXN];
SAM(){ link[0] = -1; last = tot = len[0] = 0; }
void extend(char chr){
int c = chr - 'a';
int np = ++tot, p = last;
cnt[np] = 1; len[np] = len[last] + 1;
while(p!=-1 and !ch[p][c]){
ch[p][c] = np;
p = link[p];
}
if(p==-1) link[np] = 0;
else{
int q = ch[p][c];
if(len[p]+1==len[q]) link[np] = q;
else{
int clone = ++tot;
link[clone] = link[q];
for(int i = 0; i < 26; i++) ch[clone][i] = ch[q][i];
len[clone] = len[p] + 1;
link[q] = link[np] = clone;
while(p!=-1 and ch[p][c]==q){
ch[p][c] = clone;
p = link[p];
}
}
}
last = np;
}
void calsubstring(int u = 0){
f[u] = cnt[u];
for(int c = 0; c < 26; c++){
if(!ch[u][c]) continue;
if(!f[ch[u][c]]) calsubstring(ch[u][c]);
f[u] += f[ch[u][c]];
}
}
void build(){ for(int i = 1; i <= tot; i++) G[link[i]].push_back(i); dfs(0); }
void dfs(int u){
for(int i = 0; i < (int)G[u].size(); i++){
int v = G[u][i];
dfs(v); cnt[u] += cnt[v];
}
}
void _kth(int u, string &str, int k){
if(k<=cnt[u]) return;
k -= cnt[u];
for(int i = 0; i < 26; i++){
if(!ch[u][i]) continue;
if(f[ch[u][i]]>=k){
str.append(1,char(i+'a'));
_kth(ch[u][i],str,k);
return;
}
else k -= f[ch[u][i]];
}
}
string kth(int k){
if(f[0]<k) return string("-1");
string str;
_kth(0,str,k);
return str;
}
}sam;
int main(){
scanf("%s %d %d",s,&t,&K);
n = strlen(s);
for(int i = 0; i < n; i++) sam.extend(s[i]);
if(t==1) sam.build();
else fill(sam.cnt,sam.cnt+MAXN,1);
sam.cnt[0] = 0;
sam.calsubstring();
printf("%s\n",sam.kth(K).c_str());
return 0;
}

BZOJ3998 弦论 【SAM】k小子串的更多相关文章

  1. 「BZOJ3998」[TJOI2015] 弦论(第K小子串)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3998 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input ...

  2. [TJOI2015]弦论(第k小子串)

    题意: 对于一个给定的长度为n的字符串,求出它的第k小子串. 有参数t,t为0则表示不同位置的相同子串算作一个,t为1则表示不同位置的相同子串算作多个. 题解: 首先,因为t的原因,后缀数组较难实现, ...

  3. HDU 5008 求第k小子串

    本题要求第k小的distinct子串,可以根据height数组,二分出这个第k小子串所在后缀的位置信息.由于题目要求子串起始下标尽可能小.所以再在rank数组中,二分出与当前后缀LCP大于等于所求子串 ...

  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. SPOJ SUBLEX 求第k小子串

    题目大意: 对于一个给定字符串,找到其所有不同的子串中排第k小的子串 先构建后缀自动机,然后我们可以将整个后缀自动机看做是一个DAG图,那么我们先进行拓扑排序得到 *b[N] 对于每个节点记录一个sc ...

  6. k小子串 SPOJ - SUBLEX 2

    题意: 求字典序第K大的子串 题解: 先求出后缀自动机对应节点 // 该节点后面所形成的自字符串的总数 然后直接模拟即可 #include <set> #include <map&g ...

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

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

  8. 【BZOJ3998】弦论 [SAM]

    弦论 Time Limit: 10 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description 对于一个给定长度为N的字符串,求它的第 ...

  9. BZOJ3998:[TJOI2015]弦论(SAM)

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

随机推荐

  1. 学习记录——使用PHP实现数据增删查改等基本功能(前后端分离)

    萌新初次学习服务器端语言,分享学习经验 实现功能:1.显示数据表    2.对数据进行分页    3.对数据进行增删查改 由于本萌新采用前后端完全分离方案,所以数据传输用的ajax,为了提高代码的复用 ...

  2. LeetCode844 比较含退格的字符串

    题目描述: 给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果. # 代表退格字符. 示例 1: 输入:S = "ab#c", T = ...

  3. python学习笔记 | 列表去重

    ''' @author: 人人都爱小雀斑 @time: 2020/3/10 10:29 @desc: ''' L=[1,5,7,4,6,3,0,5,8,4,4] 方法1:for循环 L1=[] for ...

  4. 【ORA】 ORA-01031:权限不足的问题

    今天创建一个用户,赋予dba权限,在plsql中选择sysdba登录,但是报错 ORA-01031 在网上找了好久最后的解决办法是 不仅仅要有dba权限 还要有这个权限: grant all priv ...

  5. ctfhub技能树—彩蛋

    彩蛋题建议大家首先自己动手去找一找 做 好 准 备 后 再 看 下 文 !           1.首页 使用域名查询工具查询子域名 2.公众号 此题关注ctfhub公众号即可拿到,不过多赘述. 3. ...

  6. ALV中layout布局控制详解

    参数的结构为SLIS_LAYOUT_ALV.结构中比较常用的字段如下: no_colhead      隐藏列标题          值为X或空 no_hotspot     headings不作为热 ...

  7. Netty的简单Demo

    这个demo是通过网上下载: 使用maven构建的: 项目结构: pom.xml: <dependencies> <dependency> <groupId>io. ...

  8. python的Counter类

    python的Counter类 Counter 集成于 dict 类,因此也可以使用字典的方法,此类返回一个以元素为 key .元素个数为 value 的 Counter 对象集合 from coll ...

  9. 浅析Linux用户空间中的Mmap

    一.MMap基础概念 mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系.实现这样的映射关系后,进程就可以采 ...

  10. 2、剑指offer-字符串——替换空格

    **题目描述** **请实现一个函数,将一个字符串中的每个空格替换成"%20".例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. ...