SPOJ 7258 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- 题解:
这题磨人啊,SPOJ跑的又慢,时限又短,压了一晚上常。
思路如下:
SAM满足性质:dfs序每一步走出来的都是一个子串,且满足从小到大顺序,关键满足不重不漏.
那么根据性质可以想出:沿着SAM走k步就是k-th子串了.
考虑优化:
记录size[x]为x节点往下可以产生的子串个数,和上题类似可以拓扑序搞出来 然后如果小于rk那么就直接减去即可.
压常技巧:
1.rg inline 不解释
2.不知为何,代码中k的输入写在函数内就快了4倍 懂得可以评论下....
- #include <algorithm>
- #include <iostream>
- #include <cstdlib>
- #include <cstring>
- #include <cstdio>
- #include <cmath>
- #define RG register
- using namespace std;
- const int N=,M=;
- char s[M];int n=,cnt=,last=,cur=,fa[M],ch[M][],dis[M],size[M];
- void build(int c){
- last=cur;cur=++cnt;
- int p=last;
- dis[cur]=++n;
- for(;p && !ch[p][c];p=fa[p])ch[p][c]=cur;
- if(!p)fa[cur]=;
- else{
- int q=ch[p][c];
- if(dis[q]==dis[p]+)fa[cur]=q;
- else{
- int nt=++cnt;
- dis[nt]=dis[p]+;
- memcpy(ch[nt],ch[q],sizeof(ch[q]));
- fa[nt]=fa[q];fa[q]=fa[cur]=nt;
- for(;ch[p][c]==q;p=fa[p])ch[p][c]=nt;
- }
- }
- }
- int sa[M];int c[M];
- void Flr(){
- int p;
- for(RG int i=;i<=cnt;i++)c[dis[i]]++;
- for(RG int i=;i<=n;i++)c[i]+=c[i-];
- for(RG int i=cnt;i;i--)sa[c[dis[i]]--]=i;
- for(RG int i=cnt;i;i--){
- p=sa[i];
- size[p]=;
- for(int j=;j<=;j++)
- size[p]+=size[ch[p][j]];
- }
- }
- void dfs(){
- RG int u,x=,rk;
- scanf("%d",&rk);
- while(rk)
- {
- for(int i=;i<=;i++){
- u=ch[x][i];
- if(!u)continue;
- if(size[u]>=rk){
- putchar('a'+i);
- x=u;rk--;break;
- }
- else rk-=size[u];
- }
- }
- puts("");
- }
- void work(){
- scanf("%s",s);
- for(RG int i=,l=strlen(s);i<l;i++)build(s[i]-'a');
- Flr();
- int Q,x;
- scanf("%d",&Q);
- while(Q--)dfs();
- }
- int main()
- {
- work();
- return ;
- }
SPOJ 7258 Lexicographical Substring Search的更多相关文章
- spoj 7258 Lexicographical Substring Search (后缀自动机)
spoj 7258 Lexicographical Substring Search (后缀自动机) 题意:给出一个字符串,长度为90000.询问q次,每次回答一个k,求字典序第k小的子串. 解题思路 ...
- SPOJ 7258 Lexicographical Substring Search(后缀自动机)
[题目链接] http://www.spoj.com/problems/SUBLEX/ [题目大意] 给出一个字符串,求其字典序排名第k的子串 [题解] 求出sam上每个节点被经过的次数,然后采用权值 ...
- ●SPOJ 7258 Lexicographical Substring Search
题链: http://www.spoj.com/problems/SUBLEX/题解: 后缀自动机. 首先,因为相同的子串都被存在了自动机的同一个状态里面,所以这就很自然的避免了重复子串的问题. 然后 ...
- SPOJ 7258 Lexicographical Substring Search [后缀自动机 DP]
题意:给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个. 第一道自己做的1A的SAM啦啦啦 很简单,建SAM后跑kth就行了 也需要按val基数排序倒着 ...
- SPOJ SUBLEX 7258. Lexicographical Substring Search
看起来像是普通的SAM+dfs...但SPOJ太慢了......倒腾了一个晚上不是WA 就是RE ..... 最后换SA写了...... Lexicographical Substring Searc ...
- SPOJ SUBLEX - Lexicographical Substring Search 后缀自动机 / 后缀数组
SUBLEX - Lexicographical Substring Search Little Daniel loves to play with strings! He always finds ...
- 【SPOJ】7258. Lexicographical Substring Search(后缀自动机)
http://www.spoj.com/problems/SUBLEX/ 后缀自动机系列完成QAQ...撒花..明天or今晚写个小结? 首先得知道:后缀自动机中,root出发到任意一个状态的路径对应一 ...
- SPOJ SUBLEX Lexicographical Substring Search - 后缀数组
题目传送门 传送门I 传送门II 题目大意 给定一个字符串,多次询问它的第$k$大本质不同的子串,输出它. 考虑后缀Trie.依次考虑每个后缀新增的本质不同的子串个数,显然,它是$n - sa[i] ...
- spoj SUBLEX (Lexicographical Substring Search) RE的欢迎来看看
SPOJ.com - Problem SUBLEX 这么裸的一个SAM,放在了死破OJ上面就是个坑. 注意用SAM做的时候输出要用一个数组存下来,然后再puts,不然一个一个字符输出会更慢. 还有一个 ...
随机推荐
- 浅谈数据结构vector
vector: 又名 向量 1.C++中的一种数据结构. 2.是一个类. 3.相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间的目的. A.使用时, ...
- Angular.js 1++快速上手
AngularJS诞生于2009年,由Misko Hevery 等人创建,后为Goole所收购.是一款优秀的前端JS框架.AngularJS有着诸多特性,最为核心的是:MVC,撗块化,自动化双向数据绑 ...
- Android广播发送失败
现在至今为止Android 8.0 不支持大部分广播收发 如果无法使用建议换至Android 7.0版本 且 minSdkVersion 24
- c#动态加载卸载DLL
前段时间工作的时候遇到一个问题.就是需要每次启动程序的时候动态替换掉某个dll,所以就百度了这方面的资料.这次记录下来让自己以后可以看. 根据自己的理解,动态卸载dll需要有以下条件: 1:dll在加 ...
- 《深入实践Spring Boot》阅读笔记之三:核心技术源代码分析
刚关注的朋友,可以回顾前两篇文章: 基础应用开发 分布式应用开发 上篇文章总结了<深入实践Spring Boot>的第二部分,本篇文章总结第三部分,也是最后一部分.这部分主要讲解核心技术的 ...
- 阿里云API网关(12)为员工创建子账号,实现分权管理API:使用RAM管理API
网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...
- docker实践
我的docker 学习笔记2 ps axf docker run -d cyf:sshd /usr/sbin -D docker ps docker-enter.sh 686 ps axf ...
- Linux探索之路1---CentOS入坑笔记整理
前言 上次跟运维去行方安装行内环境,发现linux命令还是不是很熟练.特别是用户权限分配以及vi下的快捷操作.于是决定在本地安装一个CentOS虚拟机,后面有时间就每天学习一点Linux常用命令. 作 ...
- 项目实战15—企业级堡垒机 jumpserver
本文收录在Linux运维企业架构实战系列 环境准备 系统:CentOS 7 IP:192.168.10.101 关闭selinux 和防火墙 # CentOS $ setenforce # 可以设置配 ...
- Spark:将RDD[List[String,List[Person]]]中的List[Person]通过spark api保存为hdfs文件时一直出现not serializable task,没办法找到"spark自定义Kryo序列化输入输出API"
声明:本文转自<在Spark中自定义Kryo序列化输入输出API> 在Spark中内置支持两种系列化格式:(1).Java serialization:(2).Kryo seriali ...