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

Input

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

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

Output

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

Sample Input

  1. aabc
  2. 0 3

Sample Output

  1. aab

Hint

\(N<=5*10^5\)

\(T<2\)

\(K<=1e9\)

题意:

中文题面,不解释。

题解:

把串放进后缀自动机,然后处理一遍,如果\(T=0\),则所有点权为1;否则,把每个点的\(parent\)加上当前\(size\)。然后反向拓扑,像求第\(k\)大子串如这个一样求就行了。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=1000010;
  4. char s[N];
  5. int a[N],c[N];
  6. void cmax(int &a,int b){
  7. a=max(a,b);
  8. }
  9. void cmin(int &a,int b){
  10. a=min(a,b);
  11. }
  12. struct SAM{
  13. int last,cnt;
  14. int size[N],ch[N][26],fa[N<<1],l[N<<1],sum[N];
  15. void ins(int c){
  16. int p=last,np=++cnt;last=np;l[np]=l[p]+1;
  17. for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
  18. if(!p)fa[np]=1;
  19. else{
  20. int q=ch[p][c];
  21. if(l[p]+1==l[q])fa[np]=q;
  22. else{
  23. int nq=++cnt;l[nq]=l[p]+1;
  24. memcpy(ch[nq],ch[q],sizeof ch[q]);
  25. fa[nq]=fa[q];fa[q]=fa[np]=nq;
  26. for(;ch[p][c]==q;p=fa[p])ch[p][c]=nq;
  27. }
  28. }
  29. size[np]=1;
  30. }
  31. void build(char s[]){
  32. int len=strlen(s+1);
  33. last=cnt=1;
  34. for(int i=1;i<=len;++i)ins(s[i]-'a');
  35. }
  36. void calc(int op){
  37. memset(c,0,sizeof c);
  38. for(int i=1;i<=cnt;++i)c[l[i]]++;
  39. for(int i=1;i<=cnt;++i)c[i]+=c[i-1];
  40. for(int i=1;i<=cnt;++i)a[c[l[i]]--]=i;
  41. for(int i=cnt;i;--i){
  42. int p=a[i],f=fa[p];
  43. if(op){
  44. size[f]+=size[p];
  45. }else{
  46. size[p]=1;
  47. }
  48. }
  49. size[1]=0;
  50. for(int i=cnt;i;--i){
  51. int p=a[i];
  52. sum[p]=size[p];
  53. for(int j=0;j<26;++j){
  54. if(ch[p][j])sum[p]+=sum[ch[p][j]];
  55. }
  56. }
  57. }
  58. void find(int k){
  59. int p=1;
  60. size[0]=0;
  61. while(k){
  62. int a=0;
  63. while(k>sum[ch[p][a]]&&a<26){
  64. if (ch[p][a]) k-=sum[ch[p][a]];
  65. a++;
  66. }
  67. if(a>=26){
  68. puts("-1");
  69. return;
  70. }
  71. putchar('a'+a);k-=size[ch[p][a]];
  72. if(k<=0)return;
  73. p=ch[p][a];
  74. }
  75. }
  76. }sam;
  77. int main(){
  78. cin>>s+1;
  79. sam.build(s);
  80. int t,k;
  81. cin>>t>>k;
  82. sam.calc(t);
  83. sam.find(k);
  84. }

弦论(tjoi2015,bzoj3998)(sam(后缀自动机))的更多相关文章

  1. Distinct Substrings(spoj694)(sam(后缀自动机)||sa(后缀数组))

    Given a string, we need to find the total number of its distinct substrings. Input \(T-\) number of ...

  2. LCS2 - Longest Common Substring II(spoj1812)(sam(后缀自动机)+多串LCS)

    A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\ ...

  3. LCS - Longest Common Substring(spoj1811) (sam(后缀自动机)+LCS)

    A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\ ...

  4. Lexicographical Substring Search (spoj7259) (sam(后缀自动机)+第k小子串)

    Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...

  5. Substrings(SPOJ8222) (sam(后缀自动机))

    You are given a string \(S\) which consists of 250000 lowercase latin letters at most. We define \(F ...

  6. sam(后缀自动机)

    后缀自动机ins解释 void ins(int c){ int p=last;//将当前节点的parent节点变为last int np=++cnt;//建立新节点 last=np;//将last设为 ...

  7. Luogu P3346 [ZJOI2015]诸神眷顾的幻想乡 广义SAM 后缀自动机

    题目链接 \(Click\) \(Here\) 真的是好题啊-不过在说做法之前先强调几个自己总是掉的坑点. 更新节点永远记不住往上跳\(p = fa[p]\) 新建节点永远记不住\(len[y] = ...

  8. 字符串(tjoi2016,heoi2016,bzoj4556)(sam(后缀自动机)+线段树合并+倍增+二分答案)

    佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了 一个长为\(n\)的字符串\(s\),和\(m\)个问题.佳媛姐姐必须正确回答这\(m\)个问题, ...

  9. 后缀自动机SAM学习笔记

    前言(2019.1.6) 已经是二周目了呢... 之前还是有一些东西没有理解到位 重新写一下吧 后缀自动机的一些基本概念 参考资料和例子 from hihocoder DZYO神仙翻译的神仙论文 简而 ...

随机推荐

  1. 【UML】UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)

    http://www.cnblogs.com/olvo/archive/2012/05/03/2481014.html 继承.实现.依赖.关联.聚合.组合的联系与区别 分别介绍这几种关系: 继承 指的 ...

  2. 通过ANT实现jmeter批量执行脚本、生成报告、发送邮件全套build.xml文件

    在开始通过ANT运行build.xml之前,有一步必须要做,那就是将JMeter所在目录下extras子目录里的ant-JMeter-1.1.1.jar复制到Ant所在目录lib子目录之下,这样Ant ...

  3. CSV 文件

    CSV 文件 CSV(Comma Separated Values 逗号分隔值) 是一种文件格式(如.txt..doc等),也可理解 .csv 文件就是一种特殊格式的纯文本文件.即是一组字符序列,字符 ...

  4. wcf服务契约代理链

    意图:为了是客户端代理呈现出面向对象的多态的特征 a. 服务端 .契约 实现了契约的继承这个在服务端是一点问题没有,因为oprationcontract可以继承,虽然DataContract不能实现继 ...

  5. oracle建存储过程

    进入plsql命令行 [10:42:10 liuyi@localhost]/home/liuyi>sqlplus demo/demo@180.200.3.129/meboss 连接串格式:用户名 ...

  6. 44 The shopping psychology 购物心理

    The shopping psychology 购物心理 ①People can be addicted to different things ---e. g.,alcohol, drugs, ce ...

  7. Word插入圆圈数字

    https://wenku.baidu.com/view/3260a2f0a1c7aa00b52acb5a.html Word 中在对应位置输入四位字符,选中字符(如:选中 2473 ),按 Alt+ ...

  8. (欧拉公式 很水) Coprimes -- sgu -- 1002

    链接: http://vj.acmclub.cn/contest/view.action?cid=168#problem/B Coprimes 时限:250MS     内存:4096KB     6 ...

  9. 给ubuntu系统的root设置密码:

    首先输入:sudo passwd root 然后输入当前用户的密码,例如xiaomeige这个用户的密码为xiaomeige 然后输入希望给root账户设置的密码,例如密码也为root

  10. cordova使用webrtc与网页端及移动端视频、语音聊天

    最近在做一个移动端与移动端.网页端文字.视频.语音聊天的功能.文字聊天使用websocket,在网上很多资料,也没什么难度.但是在视频.语音聊天上遇到了小小的难点.之前一直在找一些SDK想快速开发,例 ...