SPOJ Lexicographical Substring Search 后缀自动机
给你一个字符串,然后询问它第k小的factor,坑的地方在于spoj实在是太慢了,要加各种常数优化,字符集如果不压缩一下必t。。
#pragma warning(disable:4996)
#include<cstring>
#include<string>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#define maxn 90050
using namespace std; struct State{
State *suf, *go[26];
int val, cnt;
char transch;
State() :suf(0), val(0){
memset(go, 0, sizeof(go));
}
}*root, *last; State statePool[maxn * 2], *cur; void init()
{
cur = statePool;
root = last = cur++;
} void extend(int w)
{
State *p = last, *np = cur++;
np->val = p->val + 1;
np->cnt = 1;
while (p&&!p->go[w]) p->go[w] = np, p = p->suf;
if (!p) np->suf = root;
else{
State *q = p->go[w];
if (p->val + 1 == q->val){
np->suf = q;
}
else{
State *nq = cur++;
memcpy(nq->go, q->go, sizeof q->go);
nq->val = p->val + 1;
nq->cnt = 1;
nq->suf = q->suf;
q->suf = nq;
np->suf = nq;
while (p&&p->go[w] == q){
p->go[w] = nq, p = p->suf;
}
}
}
last = np;
} char str[maxn];
char ans[maxn];
int atop;
int n;
int q; int bcnt[maxn];
State *b[maxn * 2]; int main()
{
scanf("%s", str);
n = strlen(str);
init();
for (int i = 0; i < n; i++){
extend(str[i] - 'a');
}
int tot = cur - statePool;
for (int i = 0; i < tot; i++) bcnt[statePool[i].val]++;
for (int i = 1; i <= n; i++) bcnt[i] += bcnt[i - 1];
for (int i = 0; i < tot; i++) b[--bcnt[statePool[i].val]] = statePool + i;
for (int i = tot - 1; i >= 0; i--){
int kth = 0;
State *p = b[i];
for (int j = 0; j < 26; j++){
if (p->go[j]){
p->cnt += p->go[j]->cnt;
p->go[kth++] = p->go[j];
p->go[j]->transch = 'a' + j;
}
}
p->go[kth] = NULL;
}
scanf("%d", &q);
int k;
while (q--)
{
scanf("%d", &k);
State *p = root; atop = 0;
while (k){
for (int x = 0; p->go[x]; x++){
if (k > p->go[x]->cnt) k -= p->go[x]->cnt;
else {
k -= 1;
p = p->go[x];
ans[atop++] = p->transch;
break;
}
}
}
ans[atop] = '\0';
puts(ans);
}
return 0;
}
SPOJ Lexicographical Substring Search 后缀自动机的更多相关文章
- spoj 7258 Lexicographical Substring Search (后缀自动机)
spoj 7258 Lexicographical Substring Search (后缀自动机) 题意:给出一个字符串,长度为90000.询问q次,每次回答一个k,求字典序第k小的子串. 解题思路 ...
- SPOJ SUBLEX - Lexicographical Substring Search 后缀自动机 / 后缀数组
SUBLEX - Lexicographical Substring Search Little Daniel loves to play with strings! He always finds ...
- SPOJ 7258 Lexicographical Substring Search [后缀自动机 DP]
题意:给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个. 第一道自己做的1A的SAM啦啦啦 很简单,建SAM后跑kth就行了 也需要按val基数排序倒着 ...
- 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 ...
- SP7258 SUBLEX - Lexicographical Substring Search(后缀自动机)
传送门 解题思路 首先建\(sam\),然后在拓扑序上\(dp\)一下,把每个点的路径数算出来,然后统计答案时就在自动机上\(dfs\)一下,仿照平衡树那样找第\(k\)小. 代码 #include& ...
- SPOJ Lexicographical Substring Search 求字典序第k大子串 后缀自动机
题目传送门 思路:按字典序,小的字符优先选取.对于一个字符,如果以这个字符开头的子串大于等于k个,那说明这个字符是应该选的,并且选完之后,可能还要继续选.如果以这个字符开头的子串小于k个,说明这个字符 ...
- SPOJ SUBLEX Lexicographical Substring Search - 后缀数组
题目传送门 传送门I 传送门II 题目大意 给定一个字符串,多次询问它的第$k$大本质不同的子串,输出它. 考虑后缀Trie.依次考虑每个后缀新增的本质不同的子串个数,显然,它是$n - sa[i] ...
- 【SPOJ】7258. Lexicographical Substring Search(后缀自动机)
http://www.spoj.com/problems/SUBLEX/ 后缀自动机系列完成QAQ...撒花..明天or今晚写个小结? 首先得知道:后缀自动机中,root出发到任意一个状态的路径对应一 ...
随机推荐
- Python实现Linux下文件查找
import os, sys def search(curpath, s): L = os.listdir(curpath) #列出当前目录下所有文件 for subpath in L: #遍历当前目 ...
- UIScrollView,UIPageControl
#import <UIKit/UIKit.h> @interface ViewController : UIViewController<UIScrollViewDelegate&g ...
- 【风马一族_Android】第4章Android常用基本控件
第4章Android常用基本控件 控件是Android用户界面中的一个个组成元素,在介绍它们之前,读者必须了解所有控件的父类View(视图),它好比一个盛放控件的容器. 4.1View类概述 对于一个 ...
- <Linux系统hostname命令详解>
hostname命令的用法的小知识我们都知道hostname命令是查看主机名和修改主机名的. [root@apache ~]# hostname //查看本机的主机名apache.example.c ...
- 运行yum报错Error: Cannot retrieve metalink for repository: epel. Please verify its path and try again
今天给Centos通过rpm -Uvh装了个epel的扩展后,执行yum就开始报错: Error: Cannot retrieve metalink for repository: epel. Ple ...
- MongoDB的分组统计 group
mongodb中的分组聚合用$group,而且处理的最大数据量为100M如果超出需要写入到磁盘,使用格式如下: { $group: { _id: <expression>, <fie ...
- QQ互联OAuth2.0 .NET SDK 发布以及网站QQ登陆示例代码(转)
OAuth: OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的所有内容. QQ登录OAuth2 ...
- 解析php时间戳与日期的转换
php中时间戳与日期的转换. 实现功能:获取某个日期的时间戳,或获取某个时间的PHP时间戳. strtotime能将任何英文文本的日期时间描述解析为Unix时间戳,我们结合mktime()或date( ...
- centOS 一键php环境安装-php博弈
我是方少,闲着没事,感觉每次编译安装,再修改php,mysql,redis,nginx配置文件觉得把大好的青春时间都浪费掉了.如是想着,怎样一键安装 php环境和相关配置.于是拜读了一下lnmp的一键 ...
- Oracle内存管理理论篇二
目标 了解oracle内存管理方式 掌握ASMM管理方式 掌握AMM管理方式 监控内存使用 学习一个知识点时,最好先了解其历史.ORACLE近期的版本都对内存管理做了简化,从9i通过PGA_AGGRE ...