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. nodejs事件和事件循环详解

    目录 简介 nodejs中的事件循环 phase详解 timers pending callbacks idle, prepare poll轮询 check close callbacks setTi ...

  2. 【Spring】Spring 事务控制

    Spring 事务控制 Spring 事务控制介绍 JavaEE 体系进行分层开发,事务控制位于业务层,Spring 提供了分层设计业务层的事务处理解决方案. Spring 的事务控制都是基于 AOP ...

  3. 【Flutter】可滚动组件之滚动控制和监听

    前言 可以用ScrollController来控制可滚动组件的滚动位置. 接口描述 ScrollController({ // 初始滚动位置 double initialScrollOffset = ...

  4. 了解一下IO控制器与控制方式

    IO控制器 CPU无法直接控制IO设备的机械部件,因此IO设备还要有个电子部件作为CPU和IO设备机械部件之间的"中介",用于实现CPU对设备的控制. 这个电子部件就是IO控制器, ...

  5. Ubuntu_Gedit配置

    Ubuntu_Gedit配置 为了换Ubuntu的时候能够更加方便,不用再用手重新打一遍代码,丢几个Gedit配置-- External Tools gdb compile (F2) #!/bin/s ...

  6. 2019 Eclipse的下载与安装教程

    Eclipse 是一个开放源代码的.基于Java的可扩展开发平台,可以免费下载使用. 首先我们先进入这个软件的官网:https://www.eclipse.org/ 点击这个网页download下载: ...

  7. ps 2020 下载

    一款极具实用价值的作图软件--ps,由于正版价格昂贵,所以这里分享破解版的资源.b话少说,下面是下载链接和安装步骤: 下载链接: 百度网盘链接:https://pan.baidu.com/s/1XPf ...

  8. poj-DNA排序

    描述 现在有一些长度相等的DNA串(只由ACGT四个字母组成),请将它们按照逆序对的数量多少排序. 逆序对指的是字符串A中的两个字符A[i].A[j],具有i < j 且 A[i] > A ...

  9. 【小菜学网络】交换机与MAC地址学习

    上一小节介绍了 集线器 ,一种工作于物理层的简单网络设备.由于集线器采用广播的方式中继.转发物理信号,传输效率受到极大制约. 精准转发 为了解决集线器工作效率低下的尴尬,我们需要设计一种更高级的网络设 ...

  10. 手机QQ空间自动点赞登录

    学以致用~使用 Appium 模拟人类操控手机行为 V2.0在手机上运行,目前实现以下功能: 1.小黑屋模式,一分钟内给好友发100条消息然后进了好友的小黑屋 2.定时发消息提醒对象多喝热水~ 3.对 ...