BZOJ3998 弦论 【SAM】k小子串
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小子串的更多相关文章
- 「BZOJ3998」[TJOI2015] 弦论(第K小子串)
https://www.lydsy.com/JudgeOnline/problem.php?id=3998 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input ...
- [TJOI2015]弦论(第k小子串)
题意: 对于一个给定的长度为n的字符串,求出它的第k小子串. 有参数t,t为0则表示不同位置的相同子串算作一个,t为1则表示不同位置的相同子串算作多个. 题解: 首先,因为t的原因,后缀数组较难实现, ...
- HDU 5008 求第k小子串
本题要求第k小的distinct子串,可以根据height数组,二分出这个第k小子串所在后缀的位置信息.由于题目要求子串起始下标尽可能小.所以再在rank数组中,二分出与当前后缀LCP大于等于所求子串 ...
- Lexicographical Substring Search (spoj7259) (sam(后缀自动机)+第k小子串)
Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...
- SPOJ SUBLEX 求第k小子串
题目大意: 对于一个给定字符串,找到其所有不同的子串中排第k小的子串 先构建后缀自动机,然后我们可以将整个后缀自动机看做是一个DAG图,那么我们先进行拓扑排序得到 *b[N] 对于每个节点记录一个sc ...
- k小子串 SPOJ - SUBLEX 2
题意: 求字典序第K大的子串 题解: 先求出后缀自动机对应节点 // 该节点后面所形成的自字符串的总数 然后直接模拟即可 #include <set> #include <map&g ...
- BZOJ 3998: [TJOI2015]弦论 后缀自动机 后缀自动机求第k小子串
http://www.lydsy.com/JudgeOnline/problem.php?id=3998 后缀自动机应用的一个模板?需要对len进行一个排序之后再统计每个出现的数量,维护的是以该字符串 ...
- 【BZOJ3998】弦论 [SAM]
弦论 Time Limit: 10 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 对于一个给定长度为N的字符串,求它的第 ...
- BZOJ3998:[TJOI2015]弦论(SAM)
Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...
随机推荐
- nodejs事件和事件循环详解
目录 简介 nodejs中的事件循环 phase详解 timers pending callbacks idle, prepare poll轮询 check close callbacks setTi ...
- 【Spring】Spring 事务控制
Spring 事务控制 Spring 事务控制介绍 JavaEE 体系进行分层开发,事务控制位于业务层,Spring 提供了分层设计业务层的事务处理解决方案. Spring 的事务控制都是基于 AOP ...
- 【Flutter】可滚动组件之滚动控制和监听
前言 可以用ScrollController来控制可滚动组件的滚动位置. 接口描述 ScrollController({ // 初始滚动位置 double initialScrollOffset = ...
- 了解一下IO控制器与控制方式
IO控制器 CPU无法直接控制IO设备的机械部件,因此IO设备还要有个电子部件作为CPU和IO设备机械部件之间的"中介",用于实现CPU对设备的控制. 这个电子部件就是IO控制器, ...
- Ubuntu_Gedit配置
Ubuntu_Gedit配置 为了换Ubuntu的时候能够更加方便,不用再用手重新打一遍代码,丢几个Gedit配置-- External Tools gdb compile (F2) #!/bin/s ...
- 2019 Eclipse的下载与安装教程
Eclipse 是一个开放源代码的.基于Java的可扩展开发平台,可以免费下载使用. 首先我们先进入这个软件的官网:https://www.eclipse.org/ 点击这个网页download下载: ...
- ps 2020 下载
一款极具实用价值的作图软件--ps,由于正版价格昂贵,所以这里分享破解版的资源.b话少说,下面是下载链接和安装步骤: 下载链接: 百度网盘链接:https://pan.baidu.com/s/1XPf ...
- poj-DNA排序
描述 现在有一些长度相等的DNA串(只由ACGT四个字母组成),请将它们按照逆序对的数量多少排序. 逆序对指的是字符串A中的两个字符A[i].A[j],具有i < j 且 A[i] > A ...
- 【小菜学网络】交换机与MAC地址学习
上一小节介绍了 集线器 ,一种工作于物理层的简单网络设备.由于集线器采用广播的方式中继.转发物理信号,传输效率受到极大制约. 精准转发 为了解决集线器工作效率低下的尴尬,我们需要设计一种更高级的网络设 ...
- 手机QQ空间自动点赞登录
学以致用~使用 Appium 模拟人类操控手机行为 V2.0在手机上运行,目前实现以下功能: 1.小黑屋模式,一分钟内给好友发100条消息然后进了好友的小黑屋 2.定时发消息提醒对象多喝热水~ 3.对 ...