Brief Description

给定一个字符串, 您需要求出他的严格k小子串或非严格k小子串.

Algorithm Design

考察使用后缀自动机.

首先原串建SAM, 然后如果考察每个状态代表的子串的出现次数. 可以知道, 在parent树上某个节点的出现次数就是他的所有儿子的出现次数之和. 所以, 我们可以按照len基数排序, 然后根据这种拓扑序把出现次数计算出来, 同时, 我们也统计出了以某个节点为根的子树的出现次数总和.

有了每个状态的出现次数之后, 我们运行后缀自动机, 每次选择字典序最小的转移, 如果转移到达的状态所为根的子树的总出现次数大于k, 我们就可以输出这个字符, 同时k-=sum[trans[x][i]].

Code

#include <cstdio>
#include <cstring>
const int maxn = 5e5 + 1e2;
const int maxm = maxn << 1;
int N, T, k;
char str[maxn];
struct Suffix_Automaton {
int rt, last, trans[maxm][26], fa[maxm], sz, len[maxm], cnt[maxm];
int v[maxn], q[maxm], sum[maxm];
void init() {
sz = 0;
rt = last = ++sz;
}
void insert(int x) {
int p = last, np = last = ++sz;
len[np] = len[p] + 1;
cnt[np] = 1;
while (!trans[p][x] && p) {
trans[p][x] = np;
p = fa[p];
}
if (!p) {
fa[np] = 1;
} else {
int q = trans[p][x];
if (len[q] == len[p] + 1) {
fa[np] = q;
} else {
int nq = ++sz;
len[nq] = len[p] + 1;
memcpy(trans[nq], trans[q], sizeof(trans[q]));
fa[nq] = fa[q];
fa[q] = fa[np] = nq;
while (trans[p][x] == q) {
trans[p][x] = nq;
p = fa[p];
}
}
}
return;
}
void pre() {
for (int i = 1; i <= sz; i++)
v[len[i]]++;
for (int i = 1; i <= ::N; i++)
v[i] += v[i - 1];
for (int i = sz; i; i--)
q[v[len[i]]--] = i;
for (int i = sz; i; i--) {
int t = q[i];
if (T == 1)
cnt[fa[t]] += cnt[t];
else
cnt[t] = 1;
}
cnt[1] = 0;
for (int i = sz; i; i--) {
int t = q[i];
sum[t] = cnt[t];
for (int j = 0; j < 26; j++)
sum[t] += sum[trans[t][j]];
}
}
void dfs(int x, int k) {
if (k <= cnt[x])
return;
k -= cnt[x];
for (int i = 0; i < 26; i++)
if (int t = trans[x][i]) {
if (k <= sum[t]) {
putchar(i + 'a');
dfs(t, k);
return;
}
k -= sum[t];
}
}
} sam;
int main() {
#ifndef ONLINE_JUDGE
freopen("input", "r", stdin);
#endif
scanf("%s", str + 1);
N = strlen(str + 1);
scanf("%d %d", &T, &k);
sam.init();
for (int i = 1; i <= N; i++) {
sam.insert(str[i] - 'a');
}
sam.pre();
if (k > sam.sum[1])
printf("-1\n");
else
sam.dfs(1, k);
return 0;
}

[bzoj3998][TJOI2015]弦论-后缀自动机的更多相关文章

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

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

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

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

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

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

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

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

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

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

  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. [TJOI2015]弦论(后缀自动机)

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

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

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

随机推荐

  1. js立体旋转展示效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. 经典CSS坑:如何完美实现垂直水平居中?

    经典CSS坑:如何完美实现垂直水平居中? 踩了各种坑之后总结出的方法,开门见山,直接上代码和效果图.希望对读者有所帮助,后续如果有更好的方法,我也会持续更新 第一种方法:transform(个人认为最 ...

  3. php实现监控在线服务应用程序小栗子

    下面我就给大家举个栗子(例子) 某单位需要实现监控服务器状态,和监控服务器应用网站,还有需要监控服务器的中间件,数据库状态监控.听到这个任务是不是恨透头疼,这想起来是不是头疼.还好有系统可用,但是我现 ...

  4. java -cp用法

    原文出处:http://blog.csdn.net/zhuying_linux/article/details/7714194.感谢作者的分享 java -cp classpath Specify a ...

  5. junit4X系列--Rule

    原文出处:http://www.blogjava.net/DLevin/archive/2012/05/12/377955.html.感谢作者的无私分享. 初次用文字的方式记录读源码的过程,不知道怎么 ...

  6. asp.net core 部署到服务器之后外网访问不了

    部署发现问题 今天在部署.net core的时候,发现访问http://localhost:xxxx可以,但是用外网访问并不行! 开始尝试解决问题 一开始以为是nginx的问题.各种折腾,各种改配置文 ...

  7. SSMS 2005 连接 SQL SERVER 2008问题

    用本机的 Microsoft SQL Server Management Studio 2005 客户端连接数据库服务器时报错:"This version of Microsoft SQL ...

  8. Docker之容器

    容器(Container) 容器介绍: docker是通过容器来运行业务的,就像运行一个kvm虚拟机是一样的.容器其实就是从镜像创建的一个实例. 我们可以对容器进行增删改查,容器之间也是相互隔离的.和 ...

  9. Sql Server的艺术(六) SQL 子查询,创建使用返回多行的子查询,子查询创建视图

    子查询或内部查询或嵌套查询在另一个SQL查询的查询和嵌入式WHERE子句中. 子查询用于返回将被用于在主查询作为条件的数据,以进一步限制要检索的数据. 子查询可以在SELECT,INSERT,UPDA ...

  10. Core Animation 文档翻译 (第六篇)

      高级动画技巧 配置属性动画或者关键帧动画的方式是多种多样的.需要同时执行多个动画或者顺序执行多个动画的APP,可以通过高级的方式同步这些动画的timing或者将这些动画绑定在一起.我们也可以使用其 ...