Description

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

Input

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

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

Output

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

Sample Input

aabc
0 3

Sample Output

aab

解题思路:

在后缀自动机Parent树上的每个节点所代表的串都是以祖先节点为后缀的逆序子串。

利用这一性质我们可以很方便地求解一个子串出现多少次的问题(其子树内实点数)

那么这道题是求解排名的问题。

一个后缀自动机可以识别一个串所有后缀。

若按前缀查询,就是所有字串,字串出现次数和就是其母串次数和的累加。

t=0 时,认为其实点只有自己记录。

而 t=1时,认为其子节点被记录。

累加其sum值作为以此值为前缀的串个数。

最后相减逼近答案输出即可。

代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. typedef long long lnt;
  5. struct sant{
  6. int tranc[];
  7. int len;
  8. int pre;
  9. }s[];
  10. struct pnt{
  11. lnt sum;
  12. lnt size;
  13. }p[];
  14. int siz;
  15. int fin;
  16. int n,t;
  17. lnt k;
  18. char tmp[];
  19. int has[];
  20. int topo[];
  21. void Insert(int c)
  22. {
  23. int nwp,nwq,lsp,lsq;
  24. nwp=++siz;
  25. s[nwp].len=s[fin].len+;
  26. p[nwp].size=;
  27. for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre)
  28. s[lsp].tranc[c]=nwp;
  29. if(!s[lsp].tranc[c])
  30. s[nwp].pre=;
  31. else{
  32. lsq=s[lsp].tranc[c];
  33. if(s[lsq].len==s[lsp].len+)
  34. s[nwp].pre=lsq;
  35. else{
  36. nwq=++siz;
  37. s[nwq]=s[lsq];
  38. s[nwq].len=s[lsp].len+;
  39. s[nwp].pre=s[lsq].pre=nwq;
  40. while(s[lsp].tranc[c]==lsq)
  41. {
  42. s[lsp].tranc[c]=nwq;
  43. lsp=s[lsp].pre;
  44. }
  45. }
  46. }
  47. fin=nwp;
  48. return ;
  49. }
  50. int main()
  51. {
  52. fin=siz=;
  53. scanf("%s",tmp+);
  54. scanf("%d%lld",&t,&k);
  55. n=strlen(tmp+);
  56. for(int i=;i<=n;i++)
  57. Insert(tmp[i]-'a');
  58. for(int i=;i<=siz;i++)
  59. has[s[i].len]++;
  60. for(int i=;i<=siz;i++)
  61. has[i]+=has[i-];
  62. for(int i=;i<=siz;i++)
  63. topo[has[s[i].len]--]=i;
  64. for(int i=siz;i;i--)
  65. if(t)
  66. p[s[topo[i]].pre].size+=p[topo[i]].size;
  67. else
  68. p[topo[i]].size=;
  69. p[].size=;
  70. for(int i=siz;i;i--)
  71. {
  72. int h=topo[i];
  73. p[h].sum=p[h].size;
  74. for(int c=;c<;c++)
  75. if(s[h].tranc[c])
  76. p[h].sum+=p[s[h].tranc[c]].sum;
  77. }
  78. if(k>p[].sum)
  79. {
  80. puts("-1");
  81. return ;
  82. }
  83. int root=;
  84. while(k>)
  85. {
  86. for(int c=;c<;c++)
  87. {
  88. int l=s[root].tranc[c];
  89. if(!l)continue;
  90. if(k>p[l].sum)
  91. k-=p[l].sum;
  92. else{
  93. putchar('a'+c);
  94. root=s[root].tranc[c];
  95. k-=p[root].size;
  96. break;
  97. }
  98. }
  99. }
  100. return ;
  101. }
 

BZOJ3998: [TJOI2015]弦论(后缀自动机,Parent树)的更多相关文章

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

    Brief Description 给定一个字符串, 您需要求出他的严格k小子串或非严格k小子串. Algorithm Design 考察使用后缀自动机. 首先原串建SAM, 然后如果考察每个状态代表 ...

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

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

  3. 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp

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

  4. 【BZOJ-3998】弦论 后缀自动机

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

  5. [十二省联考2019]字符串问题——后缀自动机+parent树优化建图+拓扑序DP+倍增

    题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的 ...

  6. BZOJ 3998 TJOI2015 弦论 后缀自动机+DAG上的dp

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3998 题意概述:对于一个给定长度为N的字符串,求它的第K小子串是什么,T为0则表示不同位置 ...

  7. BZOJ 3998 [TJOI2015]弦论 ——后缀自动机

    直接构建后缀自动机. 然后. 然后只需要再后缀自动机的go树上类似二分的方法进行查找即可,实际上是“26分”. 然后遇到了处理right集合的问题,然后觉得在go和parent树上上传都是可以的,毕竟 ...

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

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

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

    /* 一道在树上乱搞的题目 建立出parent树来, 然后就能搞出每个节点往后能扩展出几个串, 至于位置不同算同一个的话就强制让right集合大小为1即可 然后在树上类比权值线段树找第k大26分统计一 ...

  10. BZOJ.3998.[TJOI2015]弦论(后缀自动机)

    题目链接 \(Description\) 给定字符串S,求其第K小子串.(若T=0,不同位置的相同子串算1个:否则算作多个) \(Solution\) 建SAM,处理出对于每个节点,它和它的所有后继包 ...

随机推荐

  1. 30.angularJS第一个实例

    转自:https://www.cnblogs.com/best/tag/Angular/ AngularJS 通过 ng-directives 扩展了 HTML. ng-app 指令定义一个 Angu ...

  2. BZOJ 1503 treap

    思路: treap (算是基本操作吧-..) 加减的操作数很少 就暴力好啦 每回判断一下最小的数是不是比M小 如果是 就删,继续判断 搞定. //By SiriusRen #include <c ...

  3. cf 864 F. Cities Excursions

    F. Cities Excursions There are n cities in Berland. Some pairs of them are connected with m directed ...

  4. CSS3新的UI方案

    文本新增样式 一.opacity:指定了一个元素的透明度 0~1 二.新增颜色模式rgba:很好的解决了背景透明,字体颜色不透明的需求. 三.文字阴影:text-shadow用来为文字添加阴影,而且可 ...

  5. CSS2.1(布局)

    浏览器内核 Firefox : geckoIE: tirdentSafari: webkitChrome: 一开始使用webkit 后来基于webkit开发了Blinkopera: 一开始使用pres ...

  6. BZOJ2668: [cqoi2012]交换棋子(费用流)

    Description 有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列的格子只能参与mi,j次交换. Input 第一行 ...

  7. react-native-swiper苹果正常显示,Android不显示

    在使用react-native-swiper时,最好不要放到(FlatList , SectionList,ListView,ScrollView 等)组件中,否则Android 可能不会正常显示图片 ...

  8. android 4.4最新官方源代码下载

    国内网络,日夜不休花了一个多月才下载成功android标准源代码,有些开发同人须要.已上传到网盘,分享给大家 微云地址: http://url.cn/PkkSzC 百度云盘地址(更新) http:// ...

  9. 使用Spring Mvc 转发 带着模板 父页面 之解决方法 decorators.xml

    周末了,周一布置的任务还没完毕,卡在了页面跳转上,接手了一个半截的项目要进行开发,之前没有人给培训.全靠自己爬代码,所以进度比較慢.并且加上之前没实用过 Spring Mvc 开发项目.所以有点吃力, ...

  10. hdu 5312 Sequence(数学推导——三角形数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5312 Sequence Time Limit: 2000/2000 MS (Java/Others)  ...