弦论

对于一个给定长度为 \(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. commons-logging 与log4j的关系

    参考:http://zachary-guo.iteye.com/blog/361177

  2. CSS(二)属性--文本设置

    HTML代码一 <body> <div>这是一个很黑很黑的夜晚,黑云密布,没有任何光亮透过.卖火柴的小姑娘.......</div> </body> C ...

  3. 项目导入时报错:The import javax.servlet.http.HttpServletRequest cannot be resolved 解决方法

    Error: The import javax.servlet cannot be resolved The import javax.servlet.http.HttpServletRequest ...

  4. angular 离开页面相关操作

    $scope.$on("$destroy", function() { $interval.cancel(autoRefresh);})

  5. python笔记2-变量

    变量 存东西所用 #定义变量 name='feifei'#定义变量,字符串 age=18.9#整型或者小数定义变量不需要加引号 print(name) print(age) name2="w ...

  6. 学习python二三事儿(二)

    多个变量赋值 Python允许你同时为多个变量赋值.例如: a = b = c = 1 以上实例,创建一个整型对象,值为1,三个变量被分配到相同的内存空间上. 您也可以为多个对象指定多个变量.例如: ...

  7. Android开发 ---基本UI组件2:图像按钮、单选按钮监听、多选按钮监听、开关

    Android开发 ---基本UI组件2 1.activity_main.xml 描述: 定义一个按钮 <?xml version="1.0" encoding=" ...

  8. ios 第4天

    dealloc method  会在对象释放前调用这个方法(函数)  可以让对象在释放前把一些自己申请的对象 先释放了    满足 谁申请  谁释放 的原则 例如    dealloc 会自动调用   ...

  9. MVC扩展之HtmlHelper辅助方法

    1.什么是HtmlHelper辅助方法?其实就是HtmlHelper类的扩展方法,如下所示: namespace System.Web.Mvc.Html { public static class F ...

  10. 福大软工 · 第八次作业(课堂实战)——项目UML设计(团队)

    团队 学号 姓名 本次作业博客链接 031602428 苏路明(组长) https://www.cnblogs.com/Sulumer/p/9822854.html 031602401 陈瀚霖 htt ...