SPOJ7258 SUBLEX - Lexicographical Substring Search(后缀自动机)
Little Daniel loves to play with strings! He always finds different ways to have fun with strings! Knowing that, his friend Kinan decided to test his skills so he gave him a string S and asked him Q questions of the form:
If all distinct substrings of string S were sorted lexicographically, which one will be the K-th smallest?
After knowing the huge number of questions Kinan will ask, Daniel figured out that he can't do this alone. Daniel, of course, knows your exceptional programming skills, so he asked you to write him a program which given S will answer Kinan's questions.
Example:
S = "aaa" (without quotes)
substrings of S are "a" , "a" , "a" , "aa" , "aa" , "aaa". The sorted list of substrings will be:
"a", "aa", "aaa".
Input
In the first line there is Kinan's string S (with length no more than 90000 characters). It contains only small letters of English alphabet. The second line contains a single integer Q (Q <= 500) , the number of questions Daniel will be asked. In the next Q lines a single integer K is given (0 < K < 2^31).
Output
Output consists of Q lines, the i-th contains a string which is the answer to the i-th asked question.
Example
Input:
aaa
2
2
3 Output:
aa
aaa
Edited: Some input file contains garbage at the end. Do not process them.
会做但是不会写qwq,
思路很简单:
把SAM的转移边形成的DAG图求出来,然后跟主席树查第$k$大一样,贪心枚举每一位,这个节点的某个儿子的大小大于$k$了,说明要找的串在这个儿子里,
否则就把$k$减去节点大小,继续找
一开始弄不清楚DAG图求出来的$size$和前缀树求出来的$size$有啥区别。
大概就是:
对于每个节点来说,DAG图求出来的$size$表示有多少以该节点代表的字符为起点的子串
前缀树求出来的$size$表示该节点所代表状态的$right$集合大小是多少,也就是该状态出现了多少次
这题居然卡dfs mmp
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN = ;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
char s[MAXN];
int opt, K, N;
int fa[MAXN], len[MAXN], ch[MAXN][], siz[MAXN], tot = , last = , root = ;
void insert(int x) {
int now = ++tot, pre = last; last = now; len[now] = len[pre] + ;
siz[now] = ;
for(; pre && !ch[pre][x]; pre = fa[pre]) ch[pre][x] = now;
if(!pre) fa[now] = root;
else {
int q = ch[pre][x];
if(len[q] == len[pre] + ) fa[now] = q;
else {
int nows = ++tot; len[nows] = len[pre] + ;
memcpy(ch[nows], ch[q], sizeof(ch[q]));
fa[nows] = fa[q]; fa[q] = fa[now] = nows;
for(; pre && ch[pre][x] == q; pre = fa[pre]) ch[pre][x] = nows;
}
}
}
void Query(int K) {
int now = root;
while(K) {
if(now != root) K--;
if(K <= ) break;
for(int i = ; i <= ; i++)
if(ch[now][i]) {
if(siz[ch[now][i]] >= K) {putchar(i + 'a'); now = ch[now][i]; break; }
else K -= siz[ch[now][i]];
}
}
puts("");
}
void Topsort() {
static int A[MAXN], a[MAXN];
for(int i = ; i <= tot; i++) A[len[i]]++;
for(int i = ; i <= N; i++) A[i] += A[i - ];
for(int i = tot; i >= ; i--) a[A[len[i]]--] = i;
for(int i = ; i <= tot; i++) siz[i] = ;
for(int i = tot; i ; i--)
for(int j = ; j <= ; j++)
siz[a[i]] += siz[ch[a[i]][j]];
}
int main() {
scanf("%s", s + );
N = strlen(s + );
for(int i = ; i <= N; i++) insert(s[i] - 'a');
Topsort();
int T = read();
while(T--) {
int K = read();
Query(K);
}
return ;
}
SPOJ7258 SUBLEX - Lexicographical Substring Search(后缀自动机)的更多相关文章
- SPOJ SUBLEX - Lexicographical Substring Search 后缀自动机 / 后缀数组
		
SUBLEX - Lexicographical Substring Search Little Daniel loves to play with strings! He always finds ...
 - SP7258 SUBLEX - Lexicographical Substring Search - 后缀自动机,dp
		
给定一个字符串,求本质不同排名第k小的子串 Solution 后缀自动机上每条路径对应一个本质不同的子串 按照 TRANS 图的拓扑序,DP 计算出每个点发出多少条路径 (注意区别 TRANS 图的拓 ...
 - SP7258 SUBLEX - Lexicographical Substring Search(后缀自动机)
		
传送门 解题思路 首先建\(sam\),然后在拓扑序上\(dp\)一下,把每个点的路径数算出来,然后统计答案时就在自动机上\(dfs\)一下,仿照平衡树那样找第\(k\)小. 代码 #include& ...
 - spoj 7258 Lexicographical Substring Search (后缀自动机)
		
spoj 7258 Lexicographical Substring Search (后缀自动机) 题意:给出一个字符串,长度为90000.询问q次,每次回答一个k,求字典序第k小的子串. 解题思路 ...
 - SPOJ SUBLEX Lexicographical Substring Search - 后缀数组
		
题目传送门 传送门I 传送门II 题目大意 给定一个字符串,多次询问它的第$k$大本质不同的子串,输出它. 考虑后缀Trie.依次考虑每个后缀新增的本质不同的子串个数,显然,它是$n - sa[i] ...
 - SPOJ Lexicographical Substring Search 后缀自动机
		
给你一个字符串,然后询问它第k小的factor,坑的地方在于spoj实在是太慢了,要加各种常数优化,字符集如果不压缩一下必t.. #pragma warning(disable:4996) #incl ...
 - SPOJ 7258 Lexicographical Substring Search [后缀自动机 DP]
		
题意:给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个. 第一道自己做的1A的SAM啦啦啦 很简单,建SAM后跑kth就行了 也需要按val基数排序倒着 ...
 - SPOJ7258 SUBLEX - Lexicographical Substring Search
		
传送门[洛谷] 心态崩了我有妹子 靠 我写的记忆化搜索 莫名WA了 然后心态崩了 当我正要改成bfs排序的时候 我灵光一动 md我写的i=0;i<25;i++??? 然后 改过来就A掉了T^T ...
 - Spoj  SUBLEX - Lexicographical Substring Search
		
Dicription Little Daniel loves to play with strings! He always finds different ways to have fun with ...
 
随机推荐
- 第59节:Java中的html和css语言
			
欢迎到我的简书查看我的文集 前言: HTML 英文: HyperText Markup Language内容 html是超文本标记语言,是网页语言的基础知识,html是通过标签来定义的语言,所有代码都 ...
 - txt文本处理---行未添加逗号
			
做音频处理过程中,经常遇到需要对文本进行转换,今天就遇到了一个行末加逗号的问题,找到了几种有效的方式,做个记录吧. 以下是几种方法实现: python代码实现: import os with open ...
 - Python - 安装并配置Anaconda环境
			
1- 简介 官网:https://www.anaconda.com/ Anaconda是一个用于科学计算的Python发行版,适用于数据分析的Python工具,也可以用在大数据和人工智能领域. 支持 ...
 - [2019BUAA软工助教]第0次代码作业
			
[2019BUAA软工助教]第0次代码作业 前言 本博客为完成结对项目所需的先导知识,题目不难,请认真对待 :) 欢迎来到软件工程 :) 注:本次实验为附加作业,不做不扣分,做了有附加分 Part 0 ...
 - Java核心技术及面试指南 流程控制方面的面试题答案
			
2.2.5.1 switch语句能否作用在byte上,能否作用在long上,能否作用在String上? 1 switch里可以用char,byte,short,int这些基本类型,以及它们的封装类. ...
 - 《JQuery技术内幕》读书笔记——自调用匿名函数剖析
			
Javascript语言中的自调用匿名函数格式如下: (function(){ //do somethings })(); 它还有另外两种等价写法如下: //等价写法一 (function(){ // ...
 - JavaScript递归中的作用域问题
			
需求是这样的,从子节点寻找指定className的父节点,一开始就想到递归(笨!),Dom结构如下: <div class="layer_1"> <div cla ...
 - GenericFactoryMethod泛型工厂模式实现简单IOC功能
			
1.简介 泛型工厂理论上不算Gof23中设计模式之一,但是也算是一种非常好的设计模式,个人认为,废话不多说,先写个简单的抽象工厂,在写一个泛型工厂的例子来比较抽象和泛型的区别. 2.实战 还是房屋和道 ...
 - Java后端工程师必备书单(含大后端方向相关书籍)
			
学习Java和其他技术的资源其实非常多,但是我们需要取其精华去其糟粕,选择那些最好的,最适合我们的,同时也要由浅入深,先易后难.基于这样的一个标准,我在这里为大家提供一份Java的学习资源清单. 一: ...
 - Python GUI之tkinter窗口视窗教程大集合(看这篇就够了)
			
一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 二.Tkinter 是什么 三.Tkinter 控件详细介绍 1. T ...