spoj SUBLEX (Lexicographical Substring Search) RE的欢迎来看看
这么裸的一个SAM,放在了死破OJ上面就是个坑。
注意用SAM做的时候输出要用一个数组存下来,然后再puts,不然一个一个字符输出会更慢。
还有一个就是不要多数据输入,估计最后多了几个没用的数字,反正我这么做一直无端端的RE。(就这样浪费了我一天好么!出数据的人这么不负责!)
最后就是,第k大的k是会超过子串数的。(这什么脑残配置?)
综上,这题除了坑就是坑。
代码如下:
#include <bits/stdc++.h>
using namespace std; const int N = ;
const int LAST = ;
const int K = ; struct Node {
Node *nx[K], *fail;
int dist;
long long sub; void Clear(const int d = ) {
memset(nx, , sizeof nx);
fail = ;
dist = d;
sub = ;
}
} ; struct SAM {
Node node[N << ];
Node *root, *last;
int ttNode; Node *Mem(const int d = ) {
Node *temp = node + ttNode++; temp->Clear(d); return temp;
} void Clear() {
ttNode = ;
root = last = Mem();
} void Expand(const char c) {
const int idx = c - 'a';
Node *p = last, *np = Mem(p->dist + ); for ( ; p && p->nx[idx] == ; p = p->fail) {
p->nx[idx] = np;
}
if (p) {
Node *q = p->nx[idx]; if (p->dist + != q->dist) {
Node *nq = Mem(); *nq = *q;
nq->dist = p->dist + ;
q->fail = np->fail = nq;
for ( ; p && p->nx[idx] == q; p = p->fail) {
p->nx[idx] = nq;
}
} else {
np->fail = q;
}
} else {
np->fail = root;
}
last = np;
} int dist[N << ];
Node *ptr[N << ]; void GetSub() {
memset(dist, , sizeof dist);
for (int i = ; i < ttNode; ++i) {
++dist[node[i].dist];
}
for (int i = ; i < ttNode; ++i) {
dist[i] += dist[i - ];
}
for (int i = ; i < ttNode; ++i) {
ptr[--dist[node[i].dist]] = node + i;
}
for (int i = ttNode - ; i >= ; --i) {
Node *p = ptr[i]; p->sub = ;
for (int j = ; j < K; ++j) {
if (p->nx[j]) {
p->sub += p->nx[j]->sub;
}
}
}
--node[].sub;
//for (int i = 0; i < ttNode; ++i) { cout << node[i].dist << ' '; } cout << endl;
//for (int i = 0; i < ttNode; ++i) { cout << node[i].sub << ' '; } cout << endl;
//for (int i = 0; i < ttNode; ++i) { cout << i << ": "; for (int j = 0; j < K; ++j) { cout << (node[i].nx[j] ? node[i].nx[j] - node : -1) << ' '; } cout << endl; }
}
} sam; char s[N], answer[N]; void Generate(char *const s) {
srand(time());
for (int i = ; i < LAST; ++i) {
s[i] = rand() % + 'a';
}
s[LAST] = ;
} int Run() {
//while (~scanf("%s", s)) {
//while (1) {
//Generate(s);
scanf("%s", s);
sam.Clear();
for (int i = ; s[i]; ++i) {
sam.Expand(s[i]);
}
sam.GetSub();
//cout << sam.root->sub << endl;
//if (sam.ttNode >= (N << 1)) { puts("???"); while (1) ; } int n, k; scanf("%d", &n);
while (n--) {
Node *p = sam.root;
int pos = ; scanf("%d", &k);
//if (k > sam.root->sub) { puts("..."); while (1) ; }
k = (k - ) % sam.root->sub + ;
while (k > ) {
for (int i = ; i < K; ++i) {
if (p->nx[i] == ) {
continue;
} const int cnt = p->nx[i]->sub; if (cnt >= k) {
//putchar('a' + i);
answer[pos++] = 'a' + i;
p = p->nx[i];
--k;
break;
} else {
k -= cnt;
}
}
}
answer[pos] = ;
puts(answer);
//puts("");
}
//} return ;
} int main() {
//ios::sync_with_stdio(0);
return Run();
}
UPD:还有更坑的,我开99999 * 2的SAM节点数是会TLE的,开222222 * 2才AC。我猜肯定是新增的数据各种问题,数据不在范围内了。
——written by LyonLys
spoj SUBLEX (Lexicographical Substring Search) RE的欢迎来看看的更多相关文章
- SPOJ SUBLEX - Lexicographical Substring Search 后缀自动机 / 后缀数组
SUBLEX - Lexicographical Substring Search Little Daniel loves to play with strings! He always finds ...
- SPOJ SUBLEX Lexicographical Substring Search - 后缀数组
题目传送门 传送门I 传送门II 题目大意 给定一个字符串,多次询问它的第$k$大本质不同的子串,输出它. 考虑后缀Trie.依次考虑每个后缀新增的本质不同的子串个数,显然,它是$n - sa[i] ...
- Spoj SUBLEX - Lexicographical Substring Search
Dicription Little Daniel loves to play with strings! He always finds different ways to have fun with ...
- spoj SUBLEX - Lexicographical Substring Search【SAM】
先求出SAM,然后考虑定义,点u是一个right集合,代表了长为dis[son]+1~dis[u]的串,然后根据有向边转移是添加一个字符,所以可以根据这个预处理出si[u],表示串u后加字符能有几个本 ...
- spoj 7258 Lexicographical Substring Search (后缀自动机)
spoj 7258 Lexicographical Substring Search (后缀自动机) 题意:给出一个字符串,长度为90000.询问q次,每次回答一个k,求字典序第k小的子串. 解题思路 ...
- SPOJ:SUBLEX - Lexicographical Substring Search
题面 第一行给定主串\((len<=90000)\) 第二行给定询问个数\(T<=500\) 随后给出\(T\)行\(T\)个询问,每次询问排名第\(k\)小的串,范围在\(int\)内 ...
- 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
Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...
随机推荐
- 使用Python Requests上传表单数据和文件
在Python环境下写一个HTTP客户端,发送POST请求,同时上传表单数据和文件,我们可以使用Requests模块来实现.代码如下: data = { 'name': 'nginx' } files ...
- H5C3--边框阴影box-shadow
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 用reduce装逼 之 多个数组中得出公共子数组,统计数组元素出现次数
昨天做了一道美团的面试题,要求是给N个数组,找出N个数组的公共子数组. ,,,,]; ,,,,]; ,,,,]; ,,,,]; 以上四个数组,有公共子数组2, 3,7 function main(){ ...
- poj 1144 Network(割点 入门)
Network Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 10907 Accepted: 5042 Descript ...
- java 7,8 排序异常
排序报 java.lang.IllegalArgumentException: Comparison method violates its general contract! 要明确返回-1, 0, ...
- Eclipse配置Maven详细教程
一.使用eclipse自带的maven插件 首先,现在下载Eclipse Mars之后的版本,基本上都自带了maven插件,无需自己再安装maven. 有几个注意点: 1.默认的本地仓库的目录是在C: ...
- 个人站长建议直接封掉的IP地址列表
<Valve className="org.apache.catalina.valves.RemoteAddrValve" deny="164.100.196.21 ...
- python基础--常用的模块(collections、time、datetime、random、os、sys、json、pickle)
collection模块: namedtuple:它是一个函数,是用来创建一个自定义的tuple对象的,并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素.所以我们就可以 ...
- 禁用/移除WordPress页面的评论功能
对于某些类型的WordPress站点,也许不需要在页面(page)提供评论功能,那么你可以通过下面的方法,很容易就禁用或移除WordPress页面的评论功能. 方法1:在页面编辑界面取消该页面的评论功 ...
- spring源码学习之默认标签的解析(一)
继续spring源码的学习之路,现在越来越觉得这个真的很枯燥的,而且我觉得要是自己来看源码,真的看不下去,不是没有耐心,而是真的没有头绪,我觉得结合着书来看,还是很有必要的,最起码大致的流程是能够捋清 ...