BZOJ_3998_[TJOI2015]弦论_后缀自动机

Description

对于一个给定长度为N的字符串,求它的第K小子串是什么。

Input

第一行是一个仅由小写英文字母构成的字符串S

第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个。T=1则表示不同位置的相同子串算作多个。K的意义如题所述。

Output

输出仅一行,为一个数字串,为第K小的子串。如果子串数目不足K个,则输出-1

Sample Input

aabc
0 3

Sample Output

aab

HINT

N<=5*10^5

T<2
K<=10^9

首先肯定是要一位一位确定字符,这样我们就需要两个标记。
建出后缀自动机。
设siz[i]表示i对应状态在串中出现了多少次,f[i]表示i对应子串有多少种转移方法。
siz[i]比较好求,如果表示不同位置的相同子串算作一个所有siz都为1,否则siz可以通过后缀树DP出来。
f[i]用拓扑序DP出来,初始值为siz。
然后按位确定每一位的字符即可。
 
代码:
#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 1000050
int ch[N][26],fa[N],dep[N],siz[N],cnt=1,lst=1,f[N];
int ws[N],a[N];
char w[N];
void insert(int x) {
int p=lst,np=++cnt,q,nq;
lst=np; dep[np]=dep[p]+1;
for(;p&&!ch[p][x];p=fa[p]) ch[p][x]=np;
if(!p) fa[np]=1;
else {
q=ch[p][x];
if(dep[q]==dep[p]+1) fa[np]=q;
else {
fa[nq=++cnt]=fa[q];
dep[nq]=dep[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[q]=fa[np]=nq;
for(;p&&ch[p][x]==q;p=fa[p]) ch[p][x]=nq;
}
}
siz[np]=1;
}
void print() {
int i,j;
printf("test-------------------------------------------\n");
for(i=1;i<=cnt;i++) {
printf("p=%d,siz=%d,dep=%d,fa=%d\n",i,siz[i],dep[i],fa[i]);
for(j=0;j<26;j++) {
if(ch[i][j]) {
printf("ch(%d)(%c)=%d\n",i,j+'a',ch[i][j]);
}
}
}
printf("lst=%d\n",lst);
}
int main() {
int T,K;
scanf("%s%d%d",w+1,&T,&K);
int n=strlen(w+1);
int i,j,p;
for(i=1;i<=n;i++) insert(w[i]-'a');
for(i=1;i<=cnt;i++) ws[dep[i]]++;
for(i=1;i<=n;i++) ws[i]+=ws[i-1];
for(i=cnt;i;i--) a[ws[dep[i]]--]=i;
if(T) {
for(i=cnt;i;i--) {
p=a[i]; siz[fa[p]]+=siz[p];
}
}else for(i=cnt;i;i--) siz[a[i]]=1;
for(siz[1]=0,i=cnt;i;i--) {
p=a[i];
for(f[p]=siz[p],j=0;j<26;j++) f[p]+=f[ch[p][j]];
}
if(f[1]<K) puts("-1");
else {
p=1;
while(K>siz[p]) {
K-=siz[p];
for(i=0;i<26;i++) {
if(K<=f[ch[p][i]]) {printf("%c",i+'a'),p=ch[p][i]; break;}
else K-=f[ch[p][i]];
}
}
puts("");
}
}
 

BZOJ_3998_[TJOI2015]弦论_后缀自动机的更多相关文章

  1. [bzoj3998][TJOI2015]弦论_后缀自动机

    弦论 bzoj-3998 TJOI-2015 题目大意:给定一个字符串,求其$k$小子串. 注释:$1\le length \le 5\cdot 10^5$,$1\le k\le 10^9$. 想法: ...

  2. 2018.12.15 bzoj3998: [TJOI2015]弦论(后缀自动机)

    传送门 后缀自动机基础题. 求第kkk小的子串(有可能要求本质不同) 直接建出samsamsam,然后给每个状态赋值之后在上面贪心选最小的(过程可以类比主席树/平衡树的查询操作)即可. 代码: #in ...

  3. BZOJ3998 TJOI2015 弦论 【后缀自动机】【贪心】

    Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...

  4. BZOJ3998 [TJOI2015]弦论 【后缀自动机】

    题目 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入格式 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...

  5. BZOJ3998: [TJOI2015]弦论(后缀自动机,Parent树)

    Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...

  6. [TJOI2015]弦论(后缀自动机)

    传送门 题意: 对给定字符串\(s\),求其第\(k\)小子串,重复串被计入以及不被计入这两种情况都需考虑. 思路: 首先构建后缀自动机,之后就考虑在后缀自动机上\(dp\). 我们知道如果要考虑重复 ...

  7. 【洛谷 P3975】 [TJOI2015]弦论(后缀自动机)

    题目链接 建出后缀自动机. T=0,每个子串算一次,否则每个子串算该子串的\(endpos\)集合大小次. 用\(f[i]\)表示结点\(i\)表示的\(endpos\)集合大小,则\(f[i]\)为 ...

  8. BZOJ3998 TJOI2015弦论(后缀自动机)

    先考虑相同子串视为一个.按SAM的拓扑序预处理出从每个节点开始能得到多少个本质不同子串(注意虽然一个节点对应多个子串,但到达该点时当前的子串显然是确定为其中一个的),然后按位贪心即可. 相同子串视为多 ...

  9. 【BZOJ3998】弦论(后缀自动机)

    [BZOJ3998]弦论(后缀自动机) 题面 BZOJ 题解 这题应该很简单 构建出\(SAM\)后 求出每个点往后还能构建出几个串 按照拓扑序\(dp\)一些就好了 然后就是第\(k\)大,随便搞一 ...

随机推荐

  1. HDU1021-Fibonacci Again,,找规律就好了~~~

    Fibonacci Again Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  2. php5.5编译安装

    系统环境:centos6.5PHP包:5.5.15https://wiki.swoole.com/wiki/page/177.html下载 PHP 源码包wget http://cn2.php.net ...

  3. bzoj 3223 文艺平衡树 splay 区间翻转

    Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 17715  Solved: 7769[Submit][Status][ ...

  4. 洛谷P2057 善意的投票

    题目描述 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来 ...

  5. DELL IDRAC API接口开发文档翻译及client模块

    今天和DELL官网要了一份关于服务器IDRAC 版本7/8 的API开发文档,花了一天的时间,进行了翻译,不一定全部准确,但对于英语不好的人会有所帮助.也不用重复造轮子了.下载链接: IDRAC AP ...

  6. uva 10559

    记忆话搜索 DP 看了网上题解  状态方程真是巧妙 orz #include <cstdio> #include <cstdlib> #include <cmath> ...

  7. 【纯净版windows系统】U盘启动制作图文教程

    无废话,按照步骤来就可以. 1.一个大于4G的U盘(格式化)准备好U盘,请注意制作过程中对U盘有格式化操作,有用的东西请先备份 2.UltraISO(软碟通软件)下载安装百度“软碟通”,或者访问 ht ...

  8. c++之NVI手法

    non-virtual interface(NVI)手法:令用户通过public non-virtual成员函数间接调用private virtual函数,将这个non-virtual函数称为virt ...

  9. [Tools] Scroll, Zoom, and Highlight code in a mdx-deck slide presentation with Code Surfer <🏄/>

    If you have a presentation coming up or you just need to present some documentation, then the Code S ...

  10. Windows-安装composer

    安装laravel之前必须先安装componser,点击:下载Windows安装程序 全部下一步,直到完成 目前,遇到过两个问题(国内防火墙) 还有就是Win10不支持PHP+Composer的组合, ...