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\)内 ...
随机推荐
- oracle日期格式数据修改
select * from INVOICE_NEW where ref_no='32308' update INVOICE_NEW set check_d=to_date('2015/11/16', ...
- 2011年-CUshell编程大赛
今天群里有人在做练习时遇到一个问题,$0中的分隔符使用OFS没有成功作用,遂查到这个问题,留作备忘查看 http://bbs.chinaunix.net/thread-2319120-1-1.html
- oracle忘记用户密码
在cmd命令行下输入sqlplus / as sysdba alter user system identified by abc; 就可以将system用户的密码改成abc了. alter user ...
- 一步步学习ASP.NET MVC3 (14)——Route路由
请注明转载地址:http://www.cnblogs.com/arhat 由于今天是星期六,所以多写几篇,感觉前几天的忙碌没有及时发布文章,趁着周末老魏尽力的多写几篇文章.因为本系列基本上快结束了,所 ...
- 静态页面参数传递&回调函数写法&快速排序的实现方法
相信很多人都有一种陋习,就是收藏的文章,几乎从来都没有回过头来仔细看过.这次借着这次活动的机会,在<无懈可击的web设计>一书的学习过程中,穿插着讲自己曾经收藏过的,现在觉得还有价值的文章 ...
- BZOJ 1735: [Usaco2005 jan]Muddy Fields 泥泞的牧场
Description 大雨侵袭了奶牛们的牧场.牧场是一个R * C的矩形,其中1≤R,C≤50.大雨将没有长草的土地弄得泥泞不堪,可是小心的奶牛们不想在吃草的时候弄脏她们的蹄子. 为了防止她们的蹄 ...
- zoj 3761
很简单但很虐心的一道题: 我感觉自己的算法没错,但是老是过不了:= = 但是还是把代码贴出来: 我的方法,用并查集的方式做一课树,然后对树进行遍历: 有多少棵树就有多少个点剩余: #include&l ...
- input checkbox问题和li里面包含checkbox
<input type="checkbox" id="checkbox1"/> $("input#checkbox1").cli ...
- Android游戏快速入门(一):基础储备
智能手机时代已经到来了,手机的性能正在以你我惊讶的速度提升.那么手机游戏也在迅速发展,从简单的平面单机游戏不断的向复杂的3D网络游戏发展.所以,手机游戏的市场肯定也在不断扩张.那么,作为程序猿,我们也 ...
- hadoop2.2编程:使用MapReduce编程实例(转)
原文链接:http://www.cnblogs.com/xia520pi/archive/2012/06/04/2534533.html 从网上搜到的一篇hadoop的编程实例,对于初学者真是帮助太大 ...