http://www.lydsy.com/JudgeOnline/problem.php?id=3998 (题目链接)

题意

  给出一个字符串,求它的字典序第K小的子串是什么,分情况讨论不在同一位置的相同子串需不需要重复考虑。

Solution

  对于不需要重复考虑的情况,直接就是spoj上的那道例题,而需要重复考虑的情况不过就是预处理sum的时候每次加上的是当前节点的right集合大小。

代码

  1. // bzoj3998
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<vector>
  7. #include<cstdio>
  8. #include<cmath>
  9. #include<set>
  10. #define LL long long
  11. #define inf 1<<30
  12. #define Pi acos(-1.0)
  13. #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
  14. using namespace std;
  15.  
  16. const int maxn=500010;
  17. int n,T,K;
  18. char s[maxn],ans[maxn];
  19.  
  20. namespace SAM {
  21. int last,Dargen,sz,n;
  22. int len[maxn<<1],ch[maxn<<1][26],par[maxn<<1];
  23. int b[maxn],id[maxn<<1],sum[maxn<<1],r[maxn<<1];
  24. void Extend(int c) {
  25. int np=++sz,p=last;last=np;
  26. len[np]=len[p]+1;
  27. for (;p && !ch[p][c];p=par[p]) ch[p][c]=np;
  28. if (!p) par[np]=Dargen;
  29. else {
  30. int q=ch[p][c];
  31. if (len[q]==len[p]+1) par[np]=q;
  32. else {
  33. int nq=++sz;len[nq]=len[p]+1;
  34. memcpy(ch[nq],ch[q],sizeof(ch[q]));
  35. par[nq]=par[q];
  36. par[np]=par[q]=nq;
  37. for (;p && ch[p][c]==q;p=par[p]) ch[p][c]=nq;
  38. }
  39. }
  40. }
  41. void build() {
  42. last=Dargen=sz=1;
  43. n=strlen(s+1);
  44. for (int i=1;i<=n;i++) Extend(s[i]-'a');
  45. }
  46. void pre() {
  47. for (int i=1;i<=sz;i++) b[len[i]]++;
  48. for (int i=1;i<=n;i++) b[i]+=b[i-1];
  49. for (int i=1;i<=sz;i++) id[b[len[i]]--]=i;
  50. if (!T) {
  51. for (int i=1;i<=sz;i++) r[i]=1;
  52. for (int S=0,i=sz;i>=1;i--,S=0) {
  53. for (int j=0;j<26;j++) if (ch[id[i]][j]) S+=sum[ch[id[i]][j]];
  54. sum[id[i]]=S+1;
  55. }
  56. }
  57. else {
  58. for (int p=Dargen,i=1;i<=n;i++) p=ch[p][s[i]-'a'],r[p]++;
  59. for (int i=sz;i>=1;i--) r[par[id[i]]]+=r[id[i]];
  60. for (int S=0,i=sz;i>=1;i--,S=0) {
  61. for (int j=0;j<26;j++) if (ch[id[i]][j]) S+=sum[ch[id[i]][j]];
  62. sum[id[i]]=S+r[id[i]];
  63. }
  64. }
  65. }
  66. void query() {
  67. int tot=0,p=Dargen;
  68. while (K>0) {
  69. for (int i=0;i<26;i++) if (ch[p][i]) {
  70. if (sum[ch[p][i]]>=K) {
  71. p=ch[p][i];K-=r[p];
  72. ans[++tot]=i+'a';
  73. break;
  74. }
  75. else K-=sum[ch[p][i]];
  76. }
  77. }
  78. ans[++tot]='\0';
  79. }
  80. }
  81. using namespace SAM;
  82.  
  83. int main() {
  84. scanf("%s",s+1);
  85. scanf("%d%d",&T,&K);
  86. build();
  87. pre();
  88. query();
  89. puts(ans+1);
  90. return 0;
  91. }

【bzoj3998】 TJOI2015—弦论的更多相关文章

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

    弦论 bzoj-3998 TJOI-2015 题目大意:给定一个字符串,求其$k$小子串. 注释:$1\le length \le 5\cdot 10^5$,$1\le k\le 10^9$. 想法: ...

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

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

  3. BZOJ3998 TJOI2015弦论(后缀数组+二分答案)

    先看t=1的情况.显然得求出SA(因为我不会SAM).我们一位位地确定答案.设填到了第len位,二分这一位填什么之后,在已经确定的答案所在的范围(SA上的某段区间)内二分,找到最后一个小于当前串的后缀 ...

  4. bzoj3998: [TJOI2015]弦论

    SAM小裸题qwq #include <iostream> #include <cstdio> #include <cmath> #include <cstr ...

  5. bzoj3998 [TJOI2015]弦论(SAM)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3998 [题意] 询问排名第k的子串是谁,0代表相同子串不同位置算作相同,1代表相同子串 ...

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

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

  7. 2018.12.15 bzoj3998: [TJOI2015]弦论(后缀自动机)

    传送门 后缀自动机基础题. 求第kkk小的子串(有可能要求本质不同) 直接建出samsamsam,然后给每个状态赋值之后在上面贪心选最小的(过程可以类比主席树/平衡树的查询操作)即可. 代码: #in ...

  8. BZOJ3998:[TJOI2015]弦论(SAM)

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

  9. BZOJ3998 TJOI2015 弦论 【后缀自动机】【贪心】

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

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

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

随机推荐

  1. 关于sqlserver还原不了数据库的原因

    因为备份文件需要在服务器上打成压缩包,才能进行传输,不然会丢失数据..

  2. new关键字的理解-问题型

    //输出的结果是?????????//The answer is good and gbc public class Example { String str=new String("goo ...

  3. Java调用本地接口

    先从一个经典例子说起,Java如何调用本地接口. 步骤如下: 1.创建HelloWorld.java class HelloWorld { static{ System.loadLibrary(&qu ...

  4. db2 sqlcode

    DB2错误信息(按sqlcode排序) sqlcode sqlstate 说明 000 00000 SQL语句成功完成 01xxx SQL语句成功完成,但是有警告 +012 01545 未限定的列名被 ...

  5. dotnet webservice处理数据量过大,ajax请求返回500错误解决方案

    ajax请求webservice返回json数据,数据规模过大时ajax请求会得到500的响应,webservice+ajax处理大规模的数据需要在web.config中进行如下配置: <sys ...

  6. 【BZOJ 1579】 1579: [Usaco2009 Feb]Revamping Trails 道路升级 (最短路)

    1579: [Usaco2009 Feb]Revamping Trails 道路升级 Description 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M< ...

  7. opencv----(1) mat最好用,和IplImage,cvmat 比较

    学习了几天,发现mat比IplImage,cvmat 好用太多了. 不知道确切的原文出处,我是转自新浪的一篇博文:http://blog.sina.com.cn/s/blog_534497fd0101 ...

  8. Xcode之Alcatraz

    Alcatraz的安装和使用 转发:http://www.cnblogs.com/wendingding/p/4964661.html 一.简单说明 Alcatraz 是一款 Xcode的插件管理工具 ...

  9. TOCContro控件

    TOCControl控件使用的是用伙伴控件中的数据地图,它控制图层是否在伙伴控件空显示以及和伙伴控件在符号上保持一致,TOCControl为用户提供了一个交互式的环境,如果TOCControl控件的伙 ...

  10. Android学习笔记之LinearLayout

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...