弦论

对于一个给定长度为 \(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. Python之路-python基础二(补充)

    本章内容: 三元运算 八进制,十六进制,十进制与二进制的转换 集合的修改方法 字符串常用方法            三元运算  三元运算简化了if else的语句,将四行代码简化为一行.三元运算的格式 ...

  2. asp.net webform 不显示__doPostBack的原因及某种解决方法

    为了维护老旧的asp.net webform系统,今天发现一个问题:asp.net页面没有自动生成__doPostBack方法,提示该js方法不存在.于是在网上找了大量的方法,基本上都说是IE的问题, ...

  3. 查看json数据更新情况

    #! python3 # -*- coding:utf8 -*- #主要为读取excel中接口地址,打开网页爬取url页面中数据,解析json,检查是否符合逻辑(正常) import requests ...

  4. 3.9 C++多继承

    参考:http://www.weixueyuan.net/view/6366.html 总结: C++中一个派生类中允许有两个及以上的基类,我们称这种情况为多继承 使用多继承可以描述事物之间的组合关系 ...

  5. 异步设备IO OVERLAPPED结构(设备内核对象 事件内核对象 可提醒IO)

    同步IO是指:线程在发起IO请求后会被挂起,IO完成后继续执行. 异步IO是指:线程发起IO请求后并不会挂起而是继续执行.IO完毕后会得到设备驱动程序的通知. 一.异步准备与OVERLAPPED结构 ...

  6. mybatis动态sql #和$的区别

    $和#都支持动态sql:就是你传什么它就是什么 区别: 1.#可以防止sql注入在sql执行时显示 '?' 比$安全 SELECT * FROM table WHERE id = ? 2.在使用#传入 ...

  7. springMVC拦截css与js等资源文件的解决

    写了一个demo的ssm,使用jetty容器跑的,但是在页面的时候总是发现访问资源出现404. 换了多种写法不见效. 偶然发现日志中请求被springMVC拦截了,气死我了. 解决方式: Spring ...

  8. Problem D: 求(x-y+z)*2

    Description 编写一个程序,求解以下三个函数: f(x,y,z)=2*(x-y+z) f(x,y)  =2*(x-y) f(x)    =2*(x-1) 函数调用格式见append.cc. ...

  9. 强化学习6-MC与TD的比较-实战

    # encoding:utf-8 import numpy as np import matplotlib.pylab as plt ''' 随机行走问题 0 - 1 - 2 - 3 - 4 - 5 ...

  10. MYSQL锁表问题解决

    本文实例讲述了MYSQL锁表问题的解决方法.分享给大家供大家参考,具体如下: 很多时候!一不小心就锁表!这里讲解决锁表终极方法! 案例一 ? 1 mysql>show processlist; ...