spoj 7258 SUBLEX(求第k大字串
其实对sam的拓扑排序我似懂非懂但是会用一点了。
/** @xigua */
#include <stdio.h>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <cstring>
#include <queue>
#include <set>
#include <string>
#include <map>
#include <climits>
#define PI acos(-1)
#define rep(a,b,c) for(int (a)=(b); (a)<(c); ++(a))
#define drep(a,b,c) for(int (a)=(b); (a)>(c); --(a))
#define CLR(x) memset(x, 0, sizeof(x))
#define sf scanf
#define pf printf
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = * + ;
const int ma = 1e5 + ;
const int mod = 1e9 + ;
const int INF = 1e8 + ;
const ll inf = 1e17 + ;
const db eps = 1e-;
const int MAXN = 2e5+1e3;
struct SAM{
int ch[maxn<<][];
int fa[maxn<<], len[maxn<<];
int cnt, last, root;
void init() {
root=;
memset(ch, , sizeof(ch));
memset(fa, , sizeof(fa));
last=cnt=root;
}
void add(int c) {
int p=last, np=last=++cnt;
len[np]=len[p]+;
while(!ch[p][c] && p) {
ch[p][c]=np;
p=fa[p];
}
if (p==) fa[np]=;
else {
int q = ch[p][c];
if(len[p] + == len[q]) {
fa[np] = q;
}
else {
int nq = ++cnt;
len[nq] = len[p] + ;
memcpy(ch[nq], ch[q], sizeof ch[q]);
fa[nq] = fa[q];
fa[q] = fa[np] = nq;
while(ch[p][c] == q && p) {
ch[p][c] = nq;
p = fa[p];
}
}
}
}
int find(char *s) {
int p=root, l=, c=;
int lenn=strlen(s);
for(int i = ; i < lenn; i++) {
if(ch[p][s[i] - 'a']) {
p = ch[p][s[i] - 'a'];
c++;
}
else {
while(p&&!ch[p][s[i]-'a']) p=fa[p];
if (!p) c=, p=;
else c=len[p]+, p=ch[p][s[i]-'a'];
}
l = max(l, c);
}
printf("%d\n", l);
}
}sam;
char s[maxn];
int c[maxn<<], pt[maxn<<], f[maxn];
void innt() {
memset(pt, , sizeof(pt));
memset(c, , sizeof(c));
memset(f, , sizeof(f));
}
void top() {
for (int i=; i<=sam.cnt; i++)
c[sam.len[i]]++;
for (int i=; i<=sam.cnt; i++)
c[i]+=c[i-];
for (int i=sam.cnt; i>=; i--)
pt[c[sam.len[i]]--]=i; // /*拓扑排序*/ //
for (int i=sam.cnt; i; i--) {
f[pt[i]]=;
for (int j=; j<; j++) {
f[pt[i]]+=f[sam.ch[pt[i]][j]]; //相同前缀的字符串个数
}
}
}
void solve() {
innt();
scanf("%s", s);
int lenn=strlen(s);
sam.init();
for (int i=; i<lenn; i++) {
sam.add(s[i]-'a');
}
top();
int q; scanf("%d", &q);
while(q--) {
int x; scanf("%d", &x);
int p=sam.root;
/*我们找第k大的字串就在f上转移就好了*/
while(x) {
for (int i=; i<; i++) {
if (sam.ch[p][i]) {
if (f[sam.ch[p][i]]>=x) {
putchar('a'+i);
p=sam.ch[p][i];
--x; break;
}
else x-=f[sam.ch[p][i]];
}
}
}
puts("");
}
}
int main() {
int t = , cas = ;
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
//scanf("%d", &t);
while(t--) {
// printf("Case %d: ", cas++);
solve();
}
return ;
}
spoj 7258 SUBLEX(求第k大字串的更多相关文章
- SPOJ SUBLEX 求第k小子串
题目大意: 对于一个给定字符串,找到其所有不同的子串中排第k小的子串 先构建后缀自动机,然后我们可以将整个后缀自动机看做是一个DAG图,那么我们先进行拓扑排序得到 *b[N] 对于每个节点记录一个sc ...
- spoj 7258 SUBLEX(SAM,名次)
[题目链接] http://www.spoj.com/problems/SUBLEX/en/ [题意] 给定一个字符串,询问次序为k的子串. [思路] SAM,名次 建好SAM后求出每个结点根据tra ...
- SPOJ 7258 SUBLEX 后缀数组 + 二分答案 + 前缀和
Code: #include <cstdio> #include <algorithm> #include <cstring> #define setIO(s) f ...
- hiho#1449 重复旋律6 求长度为k的串最大次数 后缀自动机
题目传送门 题目大意:求长度为k的串的最大次数,把k从1到length的所有答案全部输出. 思路: 这道题放在$SAM$里就是求长度$k$对应的所有$right$集中最大的大小. 我们以$aabab$ ...
- spoj 7258 Lexicographical Substring Search (后缀自动机)
spoj 7258 Lexicographical Substring Search (后缀自动机) 题意:给出一个字符串,长度为90000.询问q次,每次回答一个k,求字典序第k小的子串. 解题思路 ...
- 【循环数组的最大字串和】Maximal-sum Subsequence
[循环数组的最大字串和]Maximal-sum Subsequence PROBLEM 题目描述 给一个 N×N 的矩阵 M,可以取连续的一段数(必须是横着或者竖着或者斜着,这个矩阵是循环的,具体如下 ...
- bzoj 3768: spoj 4660 Binary palindrome二进制回文串
Description 给定k个长度不超过L的01串,求有多少长度为n的01串S满足: 1.该串是回文串 2.该串不存在两个不重叠的子串,在给定的k个串中. 即不存在a<=b<c<= ...
- bzoj 4504: K个串 可持久化线段树+堆
题目: Description 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一 个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次). 兔子们想 ...
- *HDU2852 树状数组(求第K小的数)
KiKi's K-Number Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
随机推荐
- x86寄存器总结
X86寄存器 ·x86寄存器分类: 8个通用寄存器:EAX.EBX.ECX.EDX.ESI.EDI.ESP.EBP 1个标志寄存器:EFLAGS 6个段寄存器:CS.DS.ES.FS.GS.SS 5个 ...
- git和svn的对比
- 20. Valid Parentheses (Stack)
Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the inpu ...
- stm32DMA
源和目标地址必须按数据传输宽度对齐 支持循环的缓冲器管理 可编程的数据传输数目:最大为65536 每一个通道都有一组寄存器 DMA_CPARx.DMA_CMARx是没有差别的,它们都可以存放外设的地址 ...
- [LeetCode_94] Binary Tree Inorder Traversal
题目链接 https://leetcode.com/problems/binary-tree-inorder-traversal/ 题意 二叉树的中序遍历 思路 中序遍历:即"左中右&quo ...
- ubuntu系列-安装jdk以及eclipse(for C++)
1.安装jdk eclipse是使用java语言开发的,一个java应用程序的运行要在java虚拟机下.在没有安装jdk的前提下,即使在ubuntu上安装了eclipse也不能使用. (1)首先在官网 ...
- 解决python3 UnicodeEncodeError: 'gbk' codec can't encode character '\xXX' in position XX(转)
原文地址:https://www.cnblogs.com/feng18/p/5646925.html 从网上抓了一些字节流,想打印出来结果发生了一下错误: UnicodeEncodeError: 'g ...
- es6问答
1. 箭头函数的特点 *箭头函数this的指向是定义时所在的对象,而不是使用时所在的对象: * 箭头函数不能做构造函数 * 不能使用argument对象 *不能使用yield命令 2.let cons ...
- 解决jenkins的内存溢出问题
在jenkins的控制台会看到如下信息: FATAL: Remote call on ime_checkcode failed java.io.IOException: Remote call on ...
- YII2中actions的作用与使用
我们常在控制器中看到一个actions的方法,这个方法具体的作用是共用一些功能相同的action,方便调用. 当然我们也可以自已写一些action来进行调用.在项目目录下创建common目录,并创建T ...