SPOJ.com - Problem SUBLEX

  这么裸的一个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的欢迎来看看的更多相关文章

  1. SPOJ SUBLEX - Lexicographical Substring Search 后缀自动机 / 后缀数组

    SUBLEX - Lexicographical Substring Search Little Daniel loves to play with strings! He always finds ...

  2. SPOJ SUBLEX Lexicographical Substring Search - 后缀数组

    题目传送门 传送门I 传送门II 题目大意 给定一个字符串,多次询问它的第$k$大本质不同的子串,输出它. 考虑后缀Trie.依次考虑每个后缀新增的本质不同的子串个数,显然,它是$n - sa[i] ...

  3. Spoj SUBLEX - Lexicographical Substring Search

    Dicription Little Daniel loves to play with strings! He always finds different ways to have fun with ...

  4. spoj SUBLEX - Lexicographical Substring Search【SAM】

    先求出SAM,然后考虑定义,点u是一个right集合,代表了长为dis[son]+1~dis[u]的串,然后根据有向边转移是添加一个字符,所以可以根据这个预处理出si[u],表示串u后加字符能有几个本 ...

  5. spoj 7258 Lexicographical Substring Search (后缀自动机)

    spoj 7258 Lexicographical Substring Search (后缀自动机) 题意:给出一个字符串,长度为90000.询问q次,每次回答一个k,求字典序第k小的子串. 解题思路 ...

  6. SPOJ:SUBLEX - Lexicographical Substring Search

    题面 第一行给定主串\((len<=90000)\) 第二行给定询问个数\(T<=500\) 随后给出\(T\)行\(T\)个询问,每次询问排名第\(k\)小的串,范围在\(int\)内 ...

  7. SPOJ 7258 Lexicographical Substring Search(后缀自动机)

    [题目链接] http://www.spoj.com/problems/SUBLEX/ [题目大意] 给出一个字符串,求其字典序排名第k的子串 [题解] 求出sam上每个节点被经过的次数,然后采用权值 ...

  8. ●SPOJ 7258 Lexicographical Substring Search

    题链: http://www.spoj.com/problems/SUBLEX/题解: 后缀自动机. 首先,因为相同的子串都被存在了自动机的同一个状态里面,所以这就很自然的避免了重复子串的问题. 然后 ...

  9. SPOJ 7258 Lexicographical Substring Search

    Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...

随机推荐

  1. 【python之路28】模块python与excel

    一.可使用的第三方库 python中处理excel表格,常用的库有xlrd(读excel)表.xlwt(写excel)表.openpyxl(可读写excel表)等.xlrd读数据较大的excel表时效 ...

  2. java-多线程的练习----妖,等待唤醒,代码重构,lock到condition

    1 需求 资源有姓名和性别. 两个线程,    一个负责给姓名和性别赋值,    一个负责获取姓名和性别的值. 要求1,运行一下,解决程序的 "妖"的问题. 要求2,实现正确数据的 ...

  3. day38 07-Spring框架Bean的时候方式

    Spring是自动帮我们创建对象的,有几种创建Bean的方式呢? 构造方法实例化:(默认无参数)其实就是反射new Instance(). 静态工厂实例化: 实例工厂实例化: 一般不会改变它实例化的方 ...

  4. Spring 社区的首个国产开源项目顺利毕业

    相信大家对上周的 <来自 Spring Cloud 官方的消息,Spring Cloud Alibaba 即将毕业>文章记忆犹新.本周,Spring Cloud Alibaba 正式毕业, ...

  5. 属性中id和name的区别

    id 在HTML中的作用:      1.用id选择相应的style sheet(风格).       2. <A ..> 链接的目的地      3.脚本语言用它找目的地(找该id的标签 ...

  6. C#截取字符串的方法小结(转)

    1.单个字符分隔用split截取 string str = "GT123_1"; string[] strArray = str.Split('_'); //输出:sArray[0 ...

  7. 为什么无法定义1px左右高度的容器

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...

  8. 用Direct2D和DWM来做简单的动画效果

    原文:用Direct2D和DWM来做简单的动画效果 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sunnyloves/article/detail ...

  9. Location 位置 history

    拆分出来地址  让地址各归其位 search案例 查找历史记录跳转

  10. python正则表达式应用 去掉标点符号