spoj 7258 SUBLEX(SAM,名次)
【题目链接】
http://www.spoj.com/problems/SUBLEX/en/
【题意】
给定一个字符串,询问次序为k的子串。
【思路】
SAM,名次
建好SAM后求出每个结点根据trans转移向下统计有多少与该结点有相同前缀的子串,每个结点只算一个,因为该结点所代表的字符串集中只可能有一个与上面统计下来的字符串前缀相同,其他的字符串都与该字符串为后缀关系。
设sum(p)为与root->p有相同前缀的字符串,设np=trans(p,x),则有转移式:
sum(p)=sigma{ sum(np) }
找名次为k的子串,只需要按照sum进行转移即可。
【代码】
#include<cstdio>
#include<cstring>
using namespace std; const int N = *1e5+; char s[N];
int root,last,sz,ch[N][],fa[N],sum[N],l[N];
void add(int x) {
int c=s[x]-'a';
int p=last,np=++sz; last=np;
l[np]=x+;
for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
if(!p) fa[np]=root;
else {
int q=ch[p][c];
if(l[p]+==l[q]) fa[np]=q;
else {
int nq=++sz; l[nq]=l[p]+;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];
fa[np]=fa[q]=nq;
for(;p&&q==ch[p][c];p=fa[p]) ch[p][c]=nq;
}
}
} int n,m,b[N],cnt[N]; void get_sum() {
for(int i=;i<=sz;i++) cnt[l[i]]++;
for(int i=;i<=n;i++) cnt[i]+=cnt[i-];
for(int i=;i<=sz;i++) b[cnt[l[i]]--]=i;
for(int i=sz;i;i--) {
int p=b[i]; sum[p]=;
for(int j=;j<;j++)
sum[p]+=sum[ch[p][j]];
}
} int main() {
scanf("%s",s);
n=strlen(s);
root=last=++sz;
for(int i=;i<n;i++) add(i);
get_sum();
scanf("%d",&m);
while(m--) {
int x,p=root; scanf("%d",&x);
while(x) {
for(int c=;c<;c++)if(ch[p][c]) {
if(sum[ch[p][c]]>=x) {
putchar('a'+c);
x--; p=ch[p][c];
break;
}
else x-=sum[ch[p][c]];
}
}
puts("");
}
return ;
}
spoj 7258 SUBLEX(SAM,名次)的更多相关文章
- spoj 7258 SUBLEX(求第k大字串
其实对sam的拓扑排序我似懂非懂但是会用一点了. /** @xigua */ #include <stdio.h> #include <cmath> #include < ...
- SPOJ 7258 SUBLEX 后缀数组 + 二分答案 + 前缀和
Code: #include <cstdio> #include <algorithm> #include <cstring> #define setIO(s) f ...
- 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
http://www.spoj.com/problems/SUBLEX/ 好难啊. 建出后缀自动机,然后在后缀自动机的每个状态上记录通过这个状态能走到的不同子串的数量.该状态能走到的所有状态的f值的和 ...
- SPOJ 7258 Lexicographical Substring Search
Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...
- SPOJ 7258 Lexicographical Substring Search [后缀自动机 DP]
题意:给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个. 第一道自己做的1A的SAM啦啦啦 很简单,建SAM后跑kth就行了 也需要按val基数排序倒着 ...
- SPOJ:SUBLEX - Lexicographical Substring Search
题面 第一行给定主串\((len<=90000)\) 第二行给定询问个数\(T<=500\) 随后给出\(T\)行\(T\)个询问,每次询问排名第\(k\)小的串,范围在\(int\)内 ...
随机推荐
- MySQL基础学习之数据查询
一般查询 SELECT * FROM 表名 SELECT 属性名 FROM 表名 条件查询 SELECT 属性名 FROM 表名 WHERE 条件表达式 查询数据值1,数据值2的表单 SELEC ...
- 寻找序列中最小的第N个元素(partition函数实现)
Partition为分割算法,用于将一个序列a[n]分为三部分:a[n]中大于某一元素x的部分,等于x的部分和小于x的部分. Partition程序如下: long Partition (long a ...
- NetBeans8 类编缉器及控制台中文乱码解决
1.类编辑器中文乱码的解决: 工具-->选项-->字体和颜色-->"语法"选项卡:右侧选择字体的地方设置一个支持中文的字体,如宋体.新宋体.微软雅黑等 2.控制台 ...
- Monitor All SQL Queries in MySQL (alias mysql profiler)
video from youtube: http://www.youtube.com/watch?v=79NWqv3aPRI one blog post: Monitor All SQL Querie ...
- Nhibernate 分页功能
cs: public IEnumerable<ArticleView> MyGetAll(int start, int limit, ref int count) { try { var ...
- Python的字符串操作和Unicode
字符串类型 str:Unicode字符串.采用''或者r''构造的字符串均为str,单引号可以用双引号或者三引号来代替.无论用哪种方式进行制定,在Python内部存储时没有区别. bytes:二进制字 ...
- easyui源码翻译1.32--Slider(滑动条)
前言 使用$.fn.slider.defaults重写默认值对象.下载该插件翻译源码 滑动条允许用户从一个有限的范围内选择一个数值.当滑块控件沿着轨道移动的时候,将会显示一个提示来表示当前值.用户可以 ...
- 【Linux远程管理】Telnet远程连接管理
Telnet,命令行界面下的远程管理工具,因为其历史非常悠久,几乎所有的操作系统都有该工具, 但是,Telnet在传输数据是是通过明文传输的,没有加密,所以现在几乎不会使用Telnet进行管理了. ( ...
- CentOS镜像163更新源
首先备份/etc/yum.repos.d/CentOS-Base.repo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-B ...
- Oracle中的阻塞锁SQL(阻塞在哪个数据上)
SELECT ( '节点 ' || a.inst_id || ' session ' || a.sid || ...