SPOJ 7258 Lexicographical Substring Search(后缀自动机)
【题目链接】 http://www.spoj.com/problems/SUBLEX/
【题目大意】
给出一个字符串,求其字典序排名第k的子串
【题解】
求出sam上每个节点被经过的次数,然后采用权值线段树上查找第k大数类似的方法,
每次确定查找范围,进入相应的子树,同时输出路径上的点即可。
【代码】
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=500005;
char s[N];
struct sam{
int p,q,np,nq,cnt,last,a[N][26],l[N],f[N];
sam(){cnt=0;last=++cnt;}
void extend(int c){
p=last;np=last=++cnt;l[np]=l[p]+1;
while(!a[p][c]&&p)a[p][c]=np,p=f[p];
if(!p)f[np]=1;
else{
q=a[p][c];
if(l[p]+1==l[q])f[np]=q;
else{
nq=++cnt;l[nq]=l[p]+1;
memcpy(a[nq],a[q],sizeof(a[q]));
f[nq]=f[q]; f[np]=f[q]=nq;
while(a[p][c]==q)a[p][c]=nq,p=f[p];
}
}
}
int b[N],x[N],mx[N];
void build(){
scanf("%s",s+1);
int len=strlen(s+1);
for(int i=1;i<=len;i++)extend(s[i]-'a');
for(int i=1;i<=cnt;i++)b[l[i]]++;
for(int i=1;i<=len;i++)b[i]+=b[i-1];
for(int i=1;i<=cnt;i++)x[b[l[i]]--]=i;
for(int i=cnt;i;i--){
mx[x[i]]=1;
for(int j=0;j<26;j++)mx[x[i]]+=mx[a[x[i]][j]];
}
}
void query(int k){
p=1;
while(k){
for(int i=0;i<26;i++)if(a[p][i]){
if(mx[a[p][i]]>=k){
putchar('a'+i);
p=a[p][i];
--k;break;
}else k-=mx[a[p][i]];
}
}puts("");
}
}sam;
int main(){
sam.build();
int Q,x;
scanf("%d",&Q);
while(Q--){
scanf("%d",&x);
sam.query(x);
}return 0;
}
SPOJ 7258 Lexicographical Substring Search(后缀自动机)的更多相关文章
- spoj 7258 Lexicographical Substring Search (后缀自动机)
spoj 7258 Lexicographical Substring Search (后缀自动机) 题意:给出一个字符串,长度为90000.询问q次,每次回答一个k,求字典序第k小的子串. 解题思路 ...
- SPOJ 7258 Lexicographical Substring Search [后缀自动机 DP]
题意:给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个. 第一道自己做的1A的SAM啦啦啦 很简单,建SAM后跑kth就行了 也需要按val基数排序倒着 ...
- 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/题解: 后缀自动机. 首先,因为相同的子串都被存在了自动机的同一个状态里面,所以这就很自然的避免了重复子串的问题. 然后 ...
- SPOJ Lexicographical Substring Search 后缀自动机
给你一个字符串,然后询问它第k小的factor,坑的地方在于spoj实在是太慢了,要加各种常数优化,字符集如果不压缩一下必t.. #pragma warning(disable:4996) #incl ...
- SPOJ SUBLEX Lexicographical Substring Search - 后缀数组
题目传送门 传送门I 传送门II 题目大意 给定一个字符串,多次询问它的第$k$大本质不同的子串,输出它. 考虑后缀Trie.依次考虑每个后缀新增的本质不同的子串个数,显然,它是$n - sa[i] ...
- SPOJ 7258 Lexicographical Substring Search
Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...
- SP7258 SUBLEX - Lexicographical Substring Search - 后缀自动机,dp
给定一个字符串,求本质不同排名第k小的子串 Solution 后缀自动机上每条路径对应一个本质不同的子串 按照 TRANS 图的拓扑序,DP 计算出每个点发出多少条路径 (注意区别 TRANS 图的拓 ...
- SPOJ7258 SUBLEX - Lexicographical Substring Search(后缀自动机)
Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...
随机推荐
- PHP基础示例:商品信息管理系统v1.1
实现目标:使用php和mysql写一个商品信息管理系统,并带有购物车功能 一.创建数据库和表 1.创建数据库和表:demodb 2.创建表格:goods 字段:商品编号,商品名称,商品类型,商品图片, ...
- <a>标签中 href="/" 和 hideFocus="true"
一:href="/" 连接到根目录 这是相对路径的根目录表示方法 可以写为 http://class.qq.com/">腾讯精品课 (绝对路径写法) 也可以为 腾讯 ...
- submit与onsubmit(转)
发生顺序:onsubmit -> submit 1.阻止表单提单: <script>function submitFun(){ //逻辑判断 return true; / ...
- 5 Logistic回归(二)
5.2.4 训练算法:随机梯度上升 梯度上升算法:在每次更新回归系数时都需要遍历整个数据集,在数十亿样本上该算法复杂度太高. 改进方法:随机梯度上升算法:一次仅用一个样本点更新回归系数. 由于可以在新 ...
- 安装solaris_11.2与windows双系统(VM10模拟实现)(一)
感慨:这周刚接触solaris,装solaris很蛋疼,一个字:慢! 在上面安装软件包依然很慢,无线网也很不稳定. 在上面搭建环境更蛋疼,一个字:惨! 什么环境之类的废话就不多说了,一般的电脑都可以. ...
- <meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Pragma" content="no-cache"><meta http-equiv="Cac ...
- J2SE知识点摘记(十二)
1. File类 下面的构造方法可以用来生成File对象 File(String directoryPath) geName()用于返回文件名,getParent()返回父目录名,exist ...
- 对手机SD卡的一些操作
首先要导入外包 log4j-1.2.16.jar 代码如下: package com.car273.util; import java.io.BufferedReader; import java.i ...
- POJ1961Period
POJ1961 #include<iostream> #include<cstdio> #include<cstring> using namespace std; ...
- python-认识Socket[入门篇]
什么是socket 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket.socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链 ...