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. vmware三种网络模式配置(转载)

    虚拟机系统安装的是Linux系统 首先,在本机上查看所有网络配置连接,使用命令:ipconfig Microsoft Windows [版本 6.1.7600]版权所有 (c) 2009 Micros ...

  2. AutoMapper introduction

    http://automapper.org/ A convention-based object-object mapper映射. 100% organic and gluten-free. Take ...

  3. Flask中的session机制

    cookie和sessioncookie:网站中,http请求是无状态的,第一次和服务器连接后并且登陆成功后,第二次请求服务器依然不能知道当前请求是哪个用户.cookie的出现就是解决了改问题,第一次 ...

  4. LINUX普通猫的拔号工具介绍

    普通猫分为串口和PCI的,请查看 <关于网络设备概述 > 普通猫的拔号工具主要有kppp和wvdial:在Redhat/Fedora中,用system-config-network 或re ...

  5. centos7默认安装没有连接网络

    1.显示所有连接 #nmcli con show 2.连接网络 #nmcli con up ens33 这个ens33是通过第一步查到的 /etc/sysconfig/network-scripts目 ...

  6. VMware安装Centos后无法上网

    参考于: http://www.xpxt.net/xtjc/win8/04194953.html

  7. php 简单加密解密

    <?php namespace App\Service; /* * @link http://kodcloud.com/ * @author warlee | e-mail:kodcloud@q ...

  8. mysql实现行拼接、列拼接

    举例:有t_person表如下: 一.mysql行拼接: 拼接某一行: 无分隔符:select   CONCAT(id,idcard,`status`,content)   from  t_perso ...

  9. DirectX11笔记(六)--Direct3D渲染2--VERTEX BUFFER

    原文:DirectX11笔记(六)--Direct3D渲染2--VERTEX BUFFER 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u0103 ...

  10. C++之正则表示,字符串是否为全字母或者全数字

    bool isLetter(std::string& inputtext){ tr1::regex reg("^[A-Za-z]+$"); bool bValid = tr ...