SPOJ 7258 (后缀自动机)
转载:http://hzwer.com/4492.html
给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个。
搞出后缀自动机
dp处理出每个点往下走能够走出多少个串。
f[i]=sigma(f[ch[i][c])+1
这个可以按Max排序之后倒着推就好了。
询问的时候看一下走下去个数是否<=k,是的话就走下去,然后–k;否则就找下一条边
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define N 180005
#define inf 1000000000
using namespace std;
char ch[N];
int Q,p,q,np,nq;
int cnt=,last=,n;
int fa[N],to[N][],l[N],s[N];
int f[N],v[N];
void extend(int c)
{
p=last;np=last=++cnt;l[np]=++n;
for(;p&&!to[p][c];p=fa[p])to[p][c]=np;
if(!p)fa[np]=;
else
{
int q=to[p][c];
if(l[p]+==l[q])fa[np]=q;
else
{
nq=++cnt;l[nq]=l[p]+;
memcpy(to[nq],to[q],sizeof(to[q]));
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
for(;to[p][c]==q;p=fa[p])to[p][c]=nq;
}
}
}
void build()
{
scanf("%s",ch);
for(char *c=ch;*c;c++)extend(*c-'a');
}
void pre()
{
for(int i=;i<=cnt;i++)v[l[i]]++;
for(int i=;i<=n;i++)v[i]+=v[i-];
for(int i=;i<=cnt;i++)s[v[l[i]]--]=i;
for(int i=cnt;i;i--)
{
f[s[i]]=;
for(int j=;j<;j++)
f[s[i]]+=f[to[s[i]][j]];
}
}
void query()
{
p=;int x;
scanf("%d",&x);
while(x)
{
for(int i=;i<;i++)
if(to[p][i])
{
if(f[to[p][i]]>=x)
{
putchar('a'+i);
p=to[p][i];
--x;break;
}
else x-=f[to[p][i]];
}
}
printf("\n");
}
int main()
{
build();
pre();
scanf("%d",&Q);
while(Q--)
query();
return ;
}
SPOJ 7258 (后缀自动机)的更多相关文章
- SPOJ NSUBSTR (后缀自动机)
SPOJ NSUBSTR Problem : 给一个长度为n的字符串,要求分别输出长度为1~n的子串的最多出现次数. Solution :首先对字符串建立后缀自动机,在根据fail指针建立出后缀树,对 ...
- SPOJ LCS 后缀自动机
用后缀自动机求两个长串的最长公共子串,效果拔群.多样例的时候memset要去掉. 解题思路就是跟CLJ的一模一样啦. #pragma warning(disable:4996) #include< ...
- SPOJ - LCS 后缀自动机入门
LCS - Longest Common Substring A string is finite sequence of characters over a non-empty finite set ...
- SPOJ LCS 后缀自动机找最大公共子串
这里用第一个字符串构建完成后缀自动机以后 不断用第二个字符串从左往右沿着后缀自动机往前走,如能找到,那么当前匹配配数加1 如果找不到,那么就不断沿着后缀树不断往前找到所能匹配到当前字符的最大长度,然后 ...
- 长度为x的本质不同的串的出现次数 SPOJ - NSUBSTR 后缀自动机简单应用
题意: 长度为x的本质不同的串的出现次数 题解: 先处理出每一个节点所对应的子串出现的次数 然后取max就好了 #include <set> #include <map> #i ...
- 多个串的最长公共子串 SPOJ - LCS2 后缀自动机
题意: 求多个串的最长公共子串 这里用的是O(n)的后缀自动机写法 我后缀数组的专题有nlog(n)写法的 题解: 对于其中的一个串建立后缀自动机 然后对于后缀自动机上面的每一个节点求出每一个节点最长 ...
- Spoj REPEATS 后缀自动机+set
REPEATS - Repeats 链接:http://www.spoj.com/problems/REPEATS 题意:求S串中某个子串连续循环次数最多的次数. 想法: 从暴力开始,枚举所有串,求出 ...
- SPOJ - SUBLEX 后缀自动机
SPOJ - SUBLEX 思路:求第k大字串,求出sam上每个节点开始能识别多少字串,然后从起点开始跑就好啦. #include<bits/stdc++.h> #define LL lo ...
- SPOJ - NSUBSTR 后缀自动机板子
SPOJ - NSUBSTR #include<bits/stdc++.h> #define LL long long #define fi first #define se second ...
随机推荐
- python杂谈
1.for循环过界保护 例如: a=len([1,2,3]) for i in range(a): for j in range(i+1:a) print(i,j) 不会报错 2.python集合和列 ...
- Linux学习篇(四)-Linux 文件管理命令详解
rootfs:根文件系统,Root FileSystem 的简称. Linux 文件命名规则 长度不超过255个字符. 不能使用/当文件名. 严格区分大小写. Linux 目录简介 / 根目录 /bo ...
- PHP-会话技术
B/S 请求响应模式是无状态的.任意的请求间不存在任何的联系,不能将请求状态保持下去. 会话技术可以给每个浏览器分配持久数据,这些数据不会随着一次请求和相应结束而销毁. COOKIE cookie 是 ...
- JavaScript浅析
目录 JacaScript概述 ECMAScript和JavaScript的关系 ECMAScript的历史: JavaScript的引入方式: 引入额外的JS文件: JavaScript的语言规范: ...
- HTML-字符实体,平方米(㎡)m²
转载自:https://blog.csdn.net/hangGe0111/article/details/80983250
- PAT甲级【2019年9月考题】——A1164 DijkstraSequence【30】
7-4 Dijkstra Sequence (30 分) Dijkstra's algorithm is one of the very famous greedy algorithms. It is ...
- 02 - Jmeter4.x正则表达式以及跨线程使用变量
话不多说 直接开撸 上图可以看出,有两个请求,其中第二个请求返回了登录超时,结合第一个登录接口来看,这个是需要header请求内容的也就是 token:当然设置一个token又怎么可能难得倒我们,无非 ...
- [Linux] 003 分区
1. 磁盘分区 使用分区编辑器再磁盘上划分几个逻辑部分 不用类的目录与文件可以存储进不同的分区 2. 分区类型 主分区 最多只能有 4 个 扩展分区 最多只能有 1 个 主分区加扩展分区最多为 4 个 ...
- 2018CCPC吉林赛区(重现赛)
http://acm.hdu.edu.cn/contests/contest_show.php?cid=867 A题,直接分块,不知道正解是什么. #include<bits/stdc++.h& ...
- Codeforces 375D D. Tree and Queries
传送门 题意: 给一棵树,每个节点有一个颜色,询问x为根的子树,出现次数大于等于k的颜色个数. 输入格式: 第一行 2 个数 n,m 表示节点数和询问数. 接下来一行 n 个数,第 i 个数 ci ...