SPOJ SUBLEX 求第k小子串
题目大意:
对于一个给定字符串,找到其所有不同的子串中排第k小的子串
先构建后缀自动机,然后我们可以将整个后缀自动机看做是一个DAG图,那么我们先进行拓扑排序得到 *b[N]
对于每个节点记录一个sc值,表示当前节点往下走可以得到不同的字符串的个数
然后从后往前,每次到达一个节点,当前节点sc赋1,然后每个可以往下走的son节点,都把这个son上的sc加到当前节点上即可
接下来得到一个排名,从root开始走,从a~z循环,通过sc正确的找到下一个进入的节点
#include <cstdio>
#include <iostream>
#include <cstring> using namespace std;
#define N 90005 struct SamNode{
int l , sc;
SamNode *son[] , *f;
}sam[N<<] , *root , *last , *b[N<<]; int cnt , num[N] , n , k;
char s[N];
void add(int x)
{
SamNode *p = &sam[++cnt] , *jp = last;
p->l = jp->l+;
last = p;
for(; jp&&!jp->son[x] ; jp=jp->f) jp->son[x] = p;
if(!jp) p->f = root;
else{
if(jp->l+ == jp->son[x]->l) p->f = jp->son[x];
else{
SamNode *r = &sam[++cnt] , *q = jp->son[x];
*r = *q; r->l = jp->l+;
p->f = q->f = r;
for( ; jp&&jp->son[x]==q ; jp=jp->f) jp->son[x] = r;
}
}
} void build()
{
int len = strlen(s);
for(int i= ; i<len ; i++) add(s[i]-'a');
for(int i= ; i<=cnt ; i++) num[sam[i].l]++;
for(int i= ; i<=len ; i++) num[i]+=num[i-];
for(int i= ; i<=cnt ; i++) b[--num[sam[i].l]] = &sam[i]; for(int i=cnt ; i>= ; i--){
b[i]->sc=;
for(int j= ; j< ; j++){
if(b[i]->son[j])
b[i]->sc+=b[i]->son[j]->sc;
}
}
} void solve()
{
scanf("%d" , &n);
char tmp[N];
int val , t;//t表示tmp中的位数
while(n--){
scanf("%d" , &k);
SamNode *cur = root;
val = , t=;
while(val<k){
for(int i= ; i< ; i++){
if(cur->son[i]){
if(val+cur->son[i]->sc<k) val+=cur->son[i]->sc;
else{
val++;
tmp[t++] = i+'a';
cur = cur->son[i];
break;
}
}
}
}
tmp[t]='\0';
printf("%s\n" , tmp);
}
} int main()
{
// freopen("a.in" , "r" , stdin);
scanf("%s" , s);
root = last = &sam[cnt=];
build();
solve();
return ;
}
SPOJ SUBLEX 求第k小子串的更多相关文章
- HDU 5008 求第k小子串
本题要求第k小的distinct子串,可以根据height数组,二分出这个第k小子串所在后缀的位置信息.由于题目要求子串起始下标尽可能小.所以再在rank数组中,二分出与当前后缀LCP大于等于所求子串 ...
- BZOJ 3998: [TJOI2015]弦论 后缀自动机 后缀自动机求第k小子串
http://www.lydsy.com/JudgeOnline/problem.php?id=3998 后缀自动机应用的一个模板?需要对len进行一个排序之后再统计每个出现的数量,维护的是以该字符串 ...
- 「BZOJ3998」[TJOI2015] 弦论(第K小子串)
https://www.lydsy.com/JudgeOnline/problem.php?id=3998 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input ...
- [TJOI2015]弦论(第k小子串)
题意: 对于一个给定的长度为n的字符串,求出它的第k小子串. 有参数t,t为0则表示不同位置的相同子串算作一个,t为1则表示不同位置的相同子串算作多个. 题解: 首先,因为t的原因,后缀数组较难实现, ...
- 树状数组求第k小的元素
int find_kth(int k) { int ans = 0,cnt = 0; for (int i = 20;i >= 0;i--) //这里的20适当的取值,与MAX_VAL有关,一般 ...
- hdu 4217 Data Structure? 树状数组求第K小
Data Structure? Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- 算法导论学习之线性时间求第k小元素+堆思想求前k大元素
对于曾经,假设要我求第k小元素.或者是求前k大元素,我可能会将元素先排序,然后就直接求出来了,可是如今有了更好的思路. 一.线性时间内求第k小元素 这个算法又是一个基于分治思想的算法. 其详细的分治思 ...
- 求第k小的数
题目链接:第k个数 题意:求n个数中第k小的数 题解: //由快速排序算法演变而来的快速选择算法 #include<iostream> using namespace std; const ...
- k小子串 SPOJ - SUBLEX 2
题意: 求字典序第K大的子串 题解: 先求出后缀自动机对应节点 // 该节点后面所形成的自字符串的总数 然后直接模拟即可 #include <set> #include <map&g ...
随机推荐
- iOS开发之真机测试
profile 位置在 /Users/userName/Library/MobileDevice/Provisioning Profiles /Users/user_lzz/Library/Mobi ...
- C++——类继承
类库:类库由类声明和实现构成.类组合了数据表示和类方法,因此提供了比函数库更加完整的程序包. 类继承:从已有的类派生出新的类,派生类继承了原有类(称为基类)的特征,包括方法. 通过类继承可以完成的工作 ...
- QBC用法
方法 说明 Restrictions.eq = Restrictions.allEq 利用Map来进行多个等于的限制 Restrictions.gt > Restrictions.ge > ...
- J2EE 第二阶段项目之编写代码(六)
三张表的增 修改 查看.明天可以完成. 周末继续统计.
- nginx日志文件切割
#!/bin/bash #脚本对日志文件进行切割 #脚本需要crontab 每天定时执行 #Nginx 日志文件的存放路径 logs_path="/../logs/" mkdir ...
- easyui dialog
<!--弹出“创建”窗口 --> <div id="dialog" class="easyui-dialog" title="创建机 ...
- CRLF CSRF XSS
http://baike.baidu.com/link?url=BXWN2I6J23thrrm6JoEnAYvmNqp83llyaydaj5RYkq--tuJKSFuMuDMIoTPnKjthRUm3 ...
- java 连接msql数据库
1.首先下载mysql的的java驱动,下载完成后把解压的mysql-connector-java-3.1.14-bin-g.jar文件放到eclipse的java项目下,然后构建路径. 2.java ...
- ARPG游戏技能系统设计
ARPG游戏的技能的前端表现, 主要指的是人物动作和特效表现, 从普遍意义上讲,大致可以分为三个阶段:起手.飞行.碰撞(爆炸). [特效可见性判断] 1.[attacker & victim] ...
- CFX客户端调用报错
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Unmarshalling Error: unex ...