SPOJ7258(后缀自动机--第k大的子串)
题目:http://www.spoj.com/problems/SUBLEX/
题意:给一个字符串,然后给Q个询问,每个询问输入一个数K,输出子串中字典序为K的字符串。
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
using namespace std;
const int N=250005;
struct State
{
State *pre,*go[26];
int step,v;
void clear()
{
v=0;
pre=0;
step=0;
memset(go,0,sizeof(go));
}
}*root,*last;
State statePool[N*2],*b[2*N],*cur;
void init()
{
cur=statePool;
root=last=cur++;
root->clear();
}
void Insert(int w)
{
State *p=last;
State *np=cur++;
np->clear();
np->step=p->step+1;
while(p&&!p->go[w])
p->go[w]=np,p=p->pre;
if(p==0)
np->pre=root;
else
{
State *q=p->go[w];
if(p->step+1==q->step)
np->pre=q;
else
{
State *nq=cur++;
nq->clear();
memcpy(nq->go,q->go,sizeof(q->go));
nq->step=p->step+1;
nq->pre=q->pre;
q->pre=nq;
np->pre=nq;
while(p&&p->go[w]==q)
p->go[w]=nq, p=p->pre;
}
}
last=np;
}
char str[N];
int son[2*N][26];
char ch[2*N][26];
int cnt[2*N],c[2*N];
void Solve(int k)
{
int ct=0;
int now=0;
while(k)
{
for(int i=0; i<c[now]; i++)
{
State *tmp=statePool+son[now][i];
if(k>tmp->v)
k-=tmp->v;
else
{
str[ct++]=ch[now][i];
now=son[now][i];
k--;
break;
}
}
}
str[ct]=0;
puts(str);
}
int main()
{
int n;
scanf("%s",str);
n=strlen(str);
init();
for(int i=0; i<n; i++)
Insert(str[i]-'a');
memset(cnt,0,sizeof(cnt));
memset(c,0,sizeof(c));
for(State *p=statePool; p!=cur; p++)
cnt[p->step]++;
for(int i=1; i<cur-statePool; i++)
cnt[i]+=cnt[i-1];
for(State *p=statePool; p!=cur; p++)
b[--cnt[p->step]]=p;
for(State *p=statePool; p!=cur; p++)
p->v=1;
int num=cur-statePool;
for(int i=num-1; i>=0; i--)
{
State *p=b[i];
for(int j=0; j<26; j++)
{
if(p->go[j])
{
int x=p-statePool;
int y=p->go[j]-statePool;
son[x][c[x]]=y;
ch[x][c[x]++]=j+'a';
p->v+=p->go[j]->v;
}
}
}
int Q,k;
scanf("%d",&Q);
while(Q--)
{
scanf("%d",&k);
Solve(k);
}
return 0;
}
SPOJ7258(后缀自动机--第k大的子串)相关推荐
- HDU - 4622 Reincarnation(后缀自动机-查询区间本质不同子串个数)
题目链接:点击查看 题目大意:给出一个长度为 n 的字符串,再给出 q 个询问,每次询问需要回答区间 [ l , r ] 内有多少个本质不同的子串 题目分析:和回文自动机那个题目一样,n * n 预处 ...
- SPOJ8222(后缀自动机--出现次数最多的子串)
题目:http://www.spoj.com/problems/NSUBSTR/ 题意:给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值.求F(1)..F(Length(S)) ...
- 【算法竞赛学习笔记】后缀自动机SAM-超经典的字符串问题详解
title : 后缀自动机 date : 2021-11-11 tags : ACM,字符串 author : Linno 前置知识 KMP,Trie,AC自动机等字符串基础 DFA(有限状态自动机) ...
- hihocoder 后缀自动机专题
一.后缀自动机基本概念的理解 1.首先后缀自动机的状态是由子串的endpos来决定的 子串的endpos是指一个子串可以在原字符串的哪些位置进行匹配, endpos构成的不同集合划分成不同的状态 关于 ...
- 【雅礼集训2017】字符串【后缀自动机】【数据分治】
题意:给定一个字符串SSS和mmm个区间[li,ri][l_i,r_i][li,ri],qqq次询问,每次给定长度为kkk的字符串www和区间[a,b][a,b][a,b],求对于所有i∈[a,b ...
- HDU 6194 后缀自动机
后缀自动机求K次出现的子串的个数: #include <iostream> #include<cstdio> #include<algorithm> #includ ...
- HDU - 5008 Boring String Problem(后缀树求本质不同第k大子串)
题目链接:点击查看 题目大意:给出一个长度为 nnn 的字符串,再给出 mmm 次询问,每次询问需要输出本质不同第 kkk 小的子串的起止位置.如果有多个答案,输出起点最小的那个.强制在线. 题目分析 ...
- HDU 5008 Boring String Problem ( 后缀数组求本质不同第k大子串)
Boring String Problem Zeronera题解 预处理sum数组记录不同字符串的个数,即sum[i] = n- sa[i] + 1 -height[i] + sum[i-1] (n为 ...
- SPOJ7258 SUBLEX 后缀自动机
题目链接 链接是洛谷有翻译的链接. 题意: 给你一个字符串,有T次询问,每次问你在整个字符串中排名为k的子串是哪一个.字符串长度<=90000,T<=500,只统计本质不同的串. 题解: ...
最新文章
- pandas基本数据操作
- adb devices 找不到设备的解决方法
- ZQCNN快速人脸检测
- html生成自定义表格,自定义js的表格插件
- 1以下数字Oracle打印缺少0,Oracle SQL中缺少關鍵字
- ES6中的高阶函数:如同 a = b = c 一样简单
- SparkSQL默认存储格式入门
- 借款条和还款条的写法(附模板)
- SIP呼叫中关于PRACK的使用
- 霍尼韦尔发力中国互联市场
- 关于跨团队合作的一些思考
- 巧用二重积分的积分中值定理
- Unity3D手游开发日记(3) - 场景加载进度条的完美方案
- 深信服“监控员工跳槽倾向”引争议,律师称未告知员工涉嫌违法
- Carson带你学Android:源码解析自定义View Draw过程
- 刘銮雄-公道不在人心,是非只在时势
- 新鲜新奇事物_用新鲜形容事物很新奇的句子
- docusign文档打不开_关于salesforce:创建Docusign文档并从其他系统发送电子邮件
- 10天精读掌握:计算机组成与设计COAD:Patterson and Hennessy 第5天 2018/10.30
- Tableau 聚合计算 - 分组求和(sum、fixed、include的使用)