弦论

对于一个给定长度为 \(N\) 的字符串,求它的第 \(K\) 小子串。

\(T\) 为 0 则表示不同位置的相同子串算作一个。\(T\) 为 1 则表示不同位置的相同子串算作多个。

\(N \leq 5 \times 10^5, \ T<2, \ K \leq 10^9\)

分析

首先建立SAM,不同字符串对应于不同的从初始节点开始的路径,然后根据题意分类:

  1. t为0则表示不同位置的相同子串算作一个,那么每个状态对应路径的字符串的出现次数只能算作1次。
  2. t为1则表示不同位置的相同子串算作多个,那么每个状态对应路径的字符串的出现次数等于它的end-pos集合大小,基数排序求拓扑序后更新即可。

时间复杂度\(O(|S|)\)

代码

把初始节点设成1,即让last=tot=1会方便许多。

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
while(isdigit(ch)) data=data*10+ch-'0',ch=getchar();
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std; co int N=5e5+5;
char s[N];
int n,t,k;
int ch[N*2][26],len[N*2],fa[N*2],siz[N*2],last=1,tot=1;
void extend(int c){
int cur=++tot;
len[cur]=len[last]+1,siz[cur]=1;
int p=last;last=cur;
for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=cur;
if(!p) fa[cur]=1;
else{
int q=ch[p][c];
if(len[q]==len[p]+1) fa[cur]=q;
else{
int clone=++tot;
len[clone]=len[p]+1,copy(ch[q],ch[q]+26,ch[clone]);
fa[clone]=fa[q],fa[q]=fa[cur]=clone;
for(;ch[p][c]==q;p=fa[p]) ch[p][c]=clone;
}
}
}
int c[N],a[N*2],sum[N*2];
int main(){
scanf("%s",s+1),n=strlen(s+1);
read(t),read(k);
for(int i=1;i<=n;++i) extend(s[i]-'a');
for(int i=1;i<=tot;++i) ++c[len[i]];
for(int i=1;i<=n;++i) c[i]+=c[i-1];
for(int i=1;i<=tot;++i) a[c[len[i]]--]=i;
for(int i=tot;i;--i){
if(t) siz[fa[a[i]]]+=siz[a[i]];
else siz[a[i]]=1;
}
siz[1]=0;
for(int i=tot;i;--i){
sum[a[i]]=siz[a[i]];
for(int c=0;c<26;++c)
if(ch[a[i]][c]) sum[a[i]]+=sum[ch[a[i]][c]];
}
if(k>sum[1]) return puts("-1"),0;
int now=1;k-=siz[now];
while(k){
int c=0;
for(;k>sum[ch[now][c]];++c) k-=sum[ch[now][c]];
putchar('a'+c);
now=ch[now][c],k-=siz[now];
}
return 0;
}

LG3975 [TJOI2015]弦论的更多相关文章

  1. BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]

    3998: [TJOI2015]弦论 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2152  Solved: 716[Submit][Status] ...

  2. Luogu P3975 [TJOI2015]弦论

    题目链接 \(Click\) \(Here\) 题目大意: 重复子串不算的第\(k\)大子串 重复子串计入的第\(k\)大子串 写法:后缀自动机. 和\(OI\) \(Wiki\)上介绍的写法不太一样 ...

  3. 洛谷 P3975 [TJOI2015]弦论 解题报告

    P3975 [TJOI2015]弦论 题目描述 为了提高智商,ZJY开始学习弦论.这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为\(n\)的字符串,求 ...

  4. 【BZOJ 3998】 3998: [TJOI2015]弦论 (SAM )

    3998: [TJOI2015]弦论 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2627  Solved: 881 Description 对于一 ...

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

    [BZOJ3998][TJOI2015]弦论 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T ...

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

    BZOJ_3998_[TJOI2015]弦论_后缀自动机 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行 ...

  7. bzoj3998: [TJOI2015]弦论(SAM+dfs)

    3998: [TJOI2015]弦论 题目:传送门 题解: SAM的入门题目(很好的复习了SAM并加强Right集合的使用) 其实对于第K小的字符串直接从root开始一通DFS就好,因为son边是直接 ...

  8. luogu P3975 [TJOI2015]弦论 SAM

    luogu P3975 [TJOI2015]弦论 链接 bzoj 思路 建出sam. 子串算多个的,统计preant tree的子树大小,否则就是大小为1 然后再统计sam的节点能走到多少串. 然后就 ...

  9. LGOJ3975 TJOI2015 弦论

    link:TJOI2015 弦论 题目大意: 给定一个字符串,输出在对该字符串所有的非空子串排序后第\(k\)个 另外的一个限制是\(T\):子串本质相同但位置不同算\(1\)或多个 \(|s| \l ...

随机推荐

  1. 修改placeholder的值---input-placeholder

    input-placeholder .box::input-placeholder 目前所有的浏览器都要加前缀 .box::-webkit-input-placeholder{ color: agba ...

  2. 【转】MySQL实现Oracle里的 rank()over(ORDER BY) 功能

    Oracle rank()和dense_rank()的区别是: –rank()是跳跃排序,有两个第二名时接下来就是第四名 –dense_rank()l是连续排序,有两个第二名时仍然跟着第三名 sele ...

  3. 十八. Python基础(18)常用模块

    十八. Python基础(18)常用模块 1 ● 常用模块及其用途 collections模块: 一些扩展的数据类型→Counter, deque, defaultdict, namedtuple, ...

  4. 网口扫盲二:Mac与Phy组成原理的简单分析(转)

    1. general 下图是网口结构简图.网口由CPU.MAC和PHY三部分组成.DMA控制器通常属于CPU的一部分,用虚线放在这里是为了表示DMA控制器可能会参与到网口数据传输中. 对于上述的三部分 ...

  5. turtle

    画一组同切圆 输入 import turtle turtle.color('red') turtle.circle(30) turtle.circle(60) turtle.circle(90) tu ...

  6. ssh 免密登陆

    A 要免密码登录要B 那么需要在A电脑上使用命令 ssh-keygen -t rsa 在~/.ssh/ 目录下生成id_rsa.pub 这个文件,然后将这个文件的内容拷到B电脑de ~/.ssh/au ...

  7. Java 内存监控(一)之 jps命令

    今天看一下Java命令行工具 jps的使用 一.命令简介 jps [ options ] [ hostid ] 不输入 [ hostid ] 内容,则默认是本机. 二.options选项的内容 -q ...

  8. delphi reintroduce作用

    当在子类中重载或者重新声明父类的虚方法时,使用  reintroduce   关键字告知编译器,可以消除警告信息. 如: TParent = class procedure proc;virtual; ...

  9. REST easy with kbmMW #20 – OpenAPI and Swagger UI

    即将推出的kbmMW更新不仅是一些bug修正,同时将包含一个新的主要功能:客户端存根生成器框架. 那什么是客户端存根生成器框架呢? 他是一个基于kbmMW smart services,可以生成由各种 ...

  10. Window下部署Maven Nexus

    Nexus下载地址:https://www.sonatype.com/download-oss-sonatype 选择相应的版本下载后,本人下载的是nexus-2.12.0-01-bundle.zip ...