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 ...
随机推荐
- 使用git命令提交远程github仓库的时候提示"rejected"(拒绝)解决办法
今天使用在自己笔记本本地磁盘上使用Git命令行执行"git push"然后输入github的用户名和密码之后,报如下错误: ![rejected] master->maste ...
- eclips引入Java源代码
window->>preferences->>Java->Installed JRES 如图所示 这是中文本的 点击“Installed JRES”选择如下图所示的jdk ...
- 在VBA中调用工作表函数
虽然VBA几乎可以完成所有工作表函数的功能,但是有时候在无法打开思路的时候,适当调用一些工作表函数也未尝不可,在VBA中调用工作表函数需要用到 WorksheetFunction对象,例如: Work ...
- 6/6 Sprint2 看板和燃尽图
页面头部的修改
- getsockname和getpeername
int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen); // 获取与某个套接字关联的本地协议地址 i ...
- 小米域名过渡JS
<script>jQuery(function($) { (function() { var $bnBar = $(''), $topBn = $('#J_topBn'), $topBnB ...
- DataTable 中Distinct操作
DataTable dt = ds.Tables[]; DataView dataView = dt.DefaultView; DataTable dtDistinct = dataView.ToTa ...
- 网页html结构右侧栏固定,左侧自适应大小。
最近写了一个项目,写页面的结构,html树形结构是有header,container,footer部分,其中container部分是右侧栏是固定宽度,左侧是自适应宽度与屏幕高度. 第一次写的博客文章是 ...
- 采购订单限价(包含阶梯价)ME_PROCESS_PO_CUST
为了能管控到钱财的每个环节,公司要求采购订单需要使用物料限价,当有报价低于先前的价格时,在采购订单保存时,更新最低限价 BADI:ME_PROCESS_PO_CUST process~item里做限价 ...
- Java网络通信
一.基本概念 1.网络程序: 能够接受另一台计算机发送过来的数据或者能够向另一台计算机发送数据的程序叫做网络程序. 2.IP 能够在网络中唯一标示一台主机的编号就是IP 3.端口号 16位数字表示 4 ...