洛谷P3975 弦论
题意:求一个串的字典序第k小的子串/本质不同第k小的子串。
解:一开始我的想法是在后缀树上找,但是不知道后缀树上的边对应的是哪些字符...
然而可以不用fail树转移,用转移边转移即可。
先建一个后缀自动机,记忆化搜索每个节点向后向后有多少个串。
然后从起点开始向后一个字符一个字符的确定。
注意每到一个新点就要判断是否结束,并把k减去在此结束的串的个数。
#include <cstdio>
#include <cstring> const int N = ; int tr[N][], len[N], fail[N], siz[N], bin[N], cnt[N], topo[N];
int top, last; inline void init() {
top = last = ;
return;
} inline void insert(char c) {
int f = c - 'a';
int p = last, np = ++top;
last = np;
len[np] = len[p] + ;
cnt[np] = ;
while(p && !tr[p][f]) {
tr[p][f] = np;
p = fail[p];
}
if(!p) {
fail[np] = ;
}
else {
int Q = tr[p][f];
if(len[Q] == len[p] + ) {
fail[np] = Q;
}
else {
int nQ = ++top;
len[nQ] = len[p] + ;
fail[nQ] = fail[Q];
fail[Q] = fail[np] = nQ;
memcpy(tr[nQ], tr[Q], sizeof(tr[Q]));
while(tr[p][f] == Q) {
tr[p][f] = nQ;
p = fail[p];
}
}
}
return;
} inline void sort() {
for(int i = ; i <= top; i++) {
bin[len[i]]++;
}
for(int i = ; i <= top; i++) {
bin[i] += bin[i - ];
}
for(int i = ; i <= top; i++) {
topo[bin[len[i]]--] = i;
}
return;
} inline void count() {
for(int i = top; i >= ; i--) {
int x = topo[i];
cnt[fail[x]] += cnt[x];
}
return;
} char s[N]; int DFS(int x) {
if(siz[x]) {
return siz[x];
}
siz[x] = cnt[x];
for(int i = ; i < ; i++) {
if(tr[x][i]) {
siz[x] += DFS(tr[x][i]);
}
}
return siz[x];
} int main() {
scanf("%s", s + );
int n = strlen(s + );
init();
for(int i = ; i <= n; i++) {
insert(s[i]);
}
sort();
int flag, k;
scanf("%d%d", &flag, &k);
if(flag) {
count();
}
else {
for(int i = ; i <= top; i++) {
cnt[i] = ;
}
} int sum = ;
for(int i = ; i <= top; i++) {
sum += cnt[i] * (len[i] - len[fail[i]]);
} int p = ;
DFS(p);
if(k > sum) {
puts("-1");
return ;
}
cnt[] = ;
while() {
//printf("k = %d %d \n", k, k == 1);
if(k == ) {
break;
}
else {
k -= cnt[p];
}
//printf("k = %d p = %d \n", k, p);
for(int i = ; i < ; i++) {
if(!tr[p][i]) {
continue;
}
if(siz[tr[p][i]] >= k) {
putchar(i + 'a');
p = tr[p][i];
break;
}
else {
k -= siz[tr[p][i]];
}
}
} return ;
}
AC代码
又思考了一下,虽然记忆化搜索会搜到重复的节点,但是这些重复所表示的是到达它的不同方案,也就是它代表的不同子串。所以需要重复统计。
这样一个节点的一条转移边其实就是它下一个字符拼上f之后能形成的子串数。
感觉好神奇...
洛谷P3975 弦论的更多相关文章
- 洛谷 P3975 [TJOI2015]弦论 解题报告
P3975 [TJOI2015]弦论 题目描述 为了提高智商,ZJY开始学习弦论.这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为\(n\)的字符串,求 ...
- 洛谷 P3975 / loj 2102 [TJOI2015] 弦论 题解【后缀自动机】【拓扑排序】
后缀自动机入门. 题目描述 为了提高智商,ZJY 开始学习弦论. 这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为 \(n\) 的字符串,求出它的第 \ ...
- [洛谷P3975][TJOI2015]弦论
题目大意:求一个字符串的第$k$大字串,$t$表示长得一样位置不同的字串是否算多个 题解:$SAM$,先求出每个位置可以到达多少个字串($Right$数组),然后在转移图上$DP$,若$t=1$,初始 ...
- 【洛谷 P3975】 [TJOI2015]弦论(后缀自动机)
题目链接 建出后缀自动机. T=0,每个子串算一次,否则每个子串算该子串的\(endpos\)集合大小次. 用\(f[i]\)表示结点\(i\)表示的\(endpos\)集合大小,则\(f[i]\)为 ...
- 洛谷P3975 跳房子 [DP,单调队列优化,二分答案]
题目传送门 跳房子 题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 n 个格子,这些格子都在同一 ...
- 洛谷1640 bzoj1854游戏 匈牙利就是又短又快
bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...
- 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.
没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...
- 洛谷P1108 低价购买[DP | LIS方案数]
题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...
- 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP
题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...
随机推荐
- 在Laravel中使用数据库事务以及捕获事务失败后的异常
Description 在Laravel中要想在数据库事务中运行一组操作,则可以在 DB facade 中使用 transaction 方法.如果在事务的闭包内抛出异常,事务将会被自动还原.如果闭包运 ...
- java连接CentOS7上的redis
这篇博客写得挺全的: https://blog.csdn.net/achenyuan/article/details/78521831?locationNum=3&fps=1 我也是跟着这篇博 ...
- Selenium简单回顾
一.Selenium介绍 1.Selenium(浏览器自动化测试框架): Selenium 是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的 ...
- 莫烦theano学习自修第四天【激励函数】
1. 定义 激励函数通常用于隐藏层,是将特征值进行过滤或者激活的算法 2.常见的激励函数 1. sigmoid (1)sigmoid() (2)ultra_fast_sigmoid() (3)hard ...
- 前端框架framework和库library的一点区别和记录
本篇纯文字,无关代码,只是一点概念的记录 关于所谓前端 首先学的是HTML5.CSS3.JavaScript这三个 之后接触了一下UI框架,如layui和bootstrap 目前是打算去学VUE和an ...
- 线程同步Volatile与Synchronized(一)
volatile 一.volatile修饰的变量具有内存可见性 volatile是变量修饰符,其修饰的变量具有内存可见性. 可见性也就是说一旦某个线程修改了该被volatile修饰的变量,它会保证修改 ...
- [BZOJ 1968] [AHOI 2005] 约数研究
Description Input 只有一行一个整数 \(N\). Output 只有一行输出,为整数 \(M\),即 \(f(1)\) 到 \(f(N)\) 的累加和. Sample Input 3 ...
- python 模块之-shelve
shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型 import shelve f = shelve ...
- BZOJ4321queue2——DP/递推
题目描述 n 个沙茶,被编号 1~n.排完队之后,每个沙茶希望,自己的相邻的两 人只要无一个人的编号和自己的编号相差为 1(+1 或-1)就行: 现在想知道,存在多少方案满足沙茶们如此不苛刻的条件. ...
- 大佬RQY真的强
今天听了大佬RQY的讲话,做一下总结吧(这里就不吹了,dalao不需要吹) 第一点,基础真的很重要.什么是基础呢?就是你今年学的觉得难到爆啊什么鬼题啊这是我学过的最zz的东西啊怎么会有这种东西啊&am ...