Lexicographical Substring Search (spoj7259) (sam(后缀自动机)+第k小子串)
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.
题意:
给定一个字符串,求排名第k小的串。
题解:
把串塞进一个后缀自动机,在图上反向拓扑求出每个点的后继串的数量,然后像在权值线段树上找第\(k\)大一样找就行了。
#include<bits/stdc++.h>
using namespace std;
const int N=2000010;
char s[N];
int a[N],c[N],ans[N];
struct SAM{
int last,cnt;
int size[N],ch[N][26],fa[N<<1],l[N<<1];
void ins(int c){
int p=last,np=++cnt;last=np;l[np]=l[p]+1;
for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
if(!p)fa[np]=1;
else{
int q=ch[p][c];
if(l[p]+1==l[q])fa[np]=q;
else{
int nq=++cnt;l[nq]=l[p]+1;
memcpy(ch[nq],ch[q],sizeof ch[q]);
fa[nq]=fa[q];fa[q]=fa[np]=nq;
for(;ch[p][c]==q;p=fa[p])ch[p][c]=nq;
size[nq]=1;
}
}
size[np]=1;
}
void build(char s[]){
int len=strlen(s+1);
last=cnt=1;
for(int i=1;i<=len;++i)ins(s[i]-'a');
}
void calc(int len){
for(int i=1;i<=cnt;++i)c[l[i]]++;
for(int i=1;i<=cnt;++i)c[i]+=c[i-1];
for(int i=1;i<=cnt;++i)a[c[l[i]]--]=i;
for(int i=cnt;i;--i){
int p=a[i];
for(int j=0;j<26;++j){
size[p]+=size[ch[p][j]];
}
}
}
void find(int k){
int p=1;
while(k){
int a=0;
while(k>size[ch[p][a]]&&a<26){
if (ch[p][a]) k-=size[ch[p][a]];
a++;
}
putchar('a'+a);k--;
p=ch[p][a];
}
}
}sam;
int main(){
cin>>s+1;
sam.build(s);
sam.calc(strlen(s+1));
int t;
cin>>t;
while(t--){
int x;
scanf("%d",&x);
sam.find(x);putchar('\n');
}
}
Lexicographical Substring Search (spoj7259) (sam(后缀自动机)+第k小子串)的更多相关文章
- LCS2 - Longest Common Substring II(spoj1812)(sam(后缀自动机)+多串LCS)
A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\ ...
- spoj SUBLEX - Lexicographical Substring Search【SAM】
先求出SAM,然后考虑定义,点u是一个right集合,代表了长为dis[son]+1~dis[u]的串,然后根据有向边转移是添加一个字符,所以可以根据这个预处理出si[u],表示串u后加字符能有几个本 ...
- spoj 7258 Lexicographical Substring Search (后缀自动机)
spoj 7258 Lexicographical Substring Search (后缀自动机) 题意:给出一个字符串,长度为90000.询问q次,每次回答一个k,求字典序第k小的子串. 解题思路 ...
- SPOJ SUBLEX - Lexicographical Substring Search 后缀自动机 / 后缀数组
SUBLEX - Lexicographical Substring Search Little Daniel loves to play with strings! He always finds ...
- [SPOJ7258]Lexicographical Substring Search
[SPOJ7258]Lexicographical Substring Search 试题描述 Little Daniel loves to play with strings! He always ...
- SPOJ SUBLEX 7258. Lexicographical Substring Search
看起来像是普通的SAM+dfs...但SPOJ太慢了......倒腾了一个晚上不是WA 就是RE ..... 最后换SA写了...... Lexicographical Substring Searc ...
- 弦论(tjoi2015,bzoj3998)(sam(后缀自动机))
对于一个给定长度为\(N\)的字符串,求它的第\(K\)小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串\(S\) 第二行为两个整数\(T\)和\(K\),\(T\)为0则表示不同 ...
- Lexicographical Substring Search SPOJ - SUBLEX (后缀自动机)
Lexicographical Substrings Search \[ Time Limit: 149 ms \quad Memory Limit: 1572864 kB \] 题意 给出一个字符串 ...
- 【SPOJ】7258. Lexicographical Substring Search(后缀自动机)
http://www.spoj.com/problems/SUBLEX/ 后缀自动机系列完成QAQ...撒花..明天or今晚写个小结? 首先得知道:后缀自动机中,root出发到任意一个状态的路径对应一 ...
随机推荐
- LevelDB Filters
[LevelDB Filters] Because of the way leveldb data is organized on disk, a single Get() call may invo ...
- Multithread之为什么spinlock必须是volatile?
[Multithread之为什么spinlock必须是volatile?] 1.编译器的优化 在本次线程内,当读取一个变量时,为提高存取速度,编译器优化时有时会先把变量读取到一个寄存器中:以后再取变量 ...
- SpringBoot进行单元测试
SpringBoot进行单元测试,需要在maven中加入以下依赖 <dependency> <groupId>org.springframework.boot</grou ...
- SSD
https://blog.csdn.net/WZZ18191171661/article/details/79444217 论文题目:SSD: Single Shot MultiBox Detecto ...
- TouchEvent里的targetTouches、touches、changedTouches的区别的具体体现是?
touches:当前屏幕上所有触摸点的集合列表 targetTouches: 绑定事件的那个结点上的触摸点的集合列表 changedTouches: 触发事件时改变的触摸点的集合 举例来说,比如div ...
- Nginx 出现413 Request Entity Too Large 错误解决方法(上传大小限制)
| 时间:2013-09-05 20:19:14 | 阅读数:485075 [导读] Nginx出现的413 Request Entity Too Large错误,这个错误一般在上传文件的时候出现,打 ...
- UX术语详解:任务流,用户流,流程图以及其它全新术语
以下内容由Mockplus(摹客)团队翻译整理,仅供学习交流,Mockplus是更快更简单的原型设计工具. 用户体验拥有一长串专业的术语和可交付内容.当在线查看UX相关职位描述时,所罗列的这类术语更是 ...
- 2018年3大UI设计趋势,你知道吗?
以下内容由Mockplus团队翻译整理,仅供学习交流,Mockplus是更快更简单的原型设计工具. 之前小编已经和大家讨论了2018年软件测试的五大趋势,现在让我们一起来看看移动UI设计在2018年会 ...
- 跳转AppStore 评分
-(void)goToAppStore { NSString *str = [NSString stringWithFormat: @"itms-apps://ax.itunes.apple ...
- .NET基础 (09)常用集合和泛型
常用集合和泛型1 int[]是引用类型还是值类型2 数组之间如何进行转换3 解释泛型的基本原理4 什么是泛型的主要约束和次要约束 常用集合和泛型1 int[]是引用类型还是值类型 数组类型是一族类型, ...