Description

对于一个给定长度为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<=10^9

Solution

建SAM

首先对于不能重复的,那么SAM里每个节点的 \(size\) ,即出现次数,直接赋为 \(1\) 即可,然后类似与平衡树找第 \(k\) 大在SAM里面dfs就好了

对于可重复的,那么一个节点的出现次数就是parent树中的子树的和,其余跟上面一模一样

  1. #include<bits/stdc++.h>
  2. #define ui unsigned int
  3. #define ll long long
  4. #define db double
  5. #define ld long double
  6. #define ull unsigned long long
  7. const int MAXN=500000+10;
  8. int n,len[MAXN<<1],fa[MAXN<<1],ch[MAXN<<1][30],cnt[MAXN],rk[MAXN<<1],las=1,tot=1,size[MAXN<<1],sum[MAXN<<1],opt,k;
  9. char s[MAXN];
  10. template<typename T> inline void read(T &x)
  11. {
  12. T data=0,w=1;
  13. char ch=0;
  14. while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
  15. if(ch=='-')w=-1,ch=getchar();
  16. while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
  17. x=data*w;
  18. }
  19. template<typename T> inline void write(T x,char ch='\0')
  20. {
  21. if(x<0)putchar('-'),x=-x;
  22. if(x>9)write(x/10);
  23. putchar(x%10+'0');
  24. if(ch!='\0')putchar(ch);
  25. }
  26. template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
  27. template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
  28. template<typename T> inline T min(T x,T y){return x<y?x:y;}
  29. template<typename T> inline T max(T x,T y){return x>y?x:y;}
  30. inline void extend(int c)
  31. {
  32. int p=las,np=++tot;
  33. las=np;
  34. len[np]=len[p]+1;size[np]=1;
  35. while(p&&!ch[p][c])ch[p][c]=np,p=fa[p];
  36. if(!p)fa[np]=1;
  37. else
  38. {
  39. int q=ch[p][c];
  40. if(len[q]==len[p]+1)fa[np]=q;
  41. else
  42. {
  43. int nq=++tot;
  44. fa[nq]=fa[q];
  45. memcpy(ch[nq],ch[q],sizeof(ch[nq]));
  46. len[nq]=len[p]+1,fa[q]=fa[np]=nq;
  47. while(p&&ch[p][c]==q)ch[p][c]=nq,p=fa[p];
  48. }
  49. }
  50. }
  51. inline void dfs(int x,int k)
  52. {
  53. k-=size[x];
  54. if(k<=0)return ;
  55. for(register int i=1;i<=26;++i)
  56. if(ch[x][i])
  57. {
  58. if(sum[ch[x][i]]>=k)
  59. {
  60. putchar(i+'a'-1);
  61. dfs(ch[x][i],k);
  62. return ;
  63. }
  64. else k-=sum[ch[x][i]];
  65. }
  66. }
  67. int main()
  68. {
  69. scanf("%s",s+1);
  70. read(opt);read(k);
  71. n=strlen(s+1);
  72. for(register int i=1;i<=n;++i)extend(s[i]-'a'+1);
  73. for(register int i=1;i<=tot;++i)cnt[len[i]]++;
  74. for(register int i=1;i<=n;++i)cnt[i]+=cnt[i-1];
  75. for(register int i=1;i<=tot;++i)rk[cnt[len[i]]--]=i;
  76. if(opt)
  77. for(register int i=tot;i>=1;--i)size[fa[rk[i]]]+=size[rk[i]];
  78. else
  79. for(register int i=1;i<=tot;++i)size[i]=1;
  80. size[1]=0;
  81. for(register int i=tot;i>=1;--i)
  82. {
  83. sum[rk[i]]=size[rk[i]];
  84. for(register int j=1;j<=26;++j)sum[rk[i]]+=sum[ch[rk[i]][j]];
  85. }
  86. if(k>sum[1])puts("-1");
  87. else dfs(1,k);
  88. return 0;
  89. }

【刷题】BZOJ 3998 [TJOI2015]弦论的更多相关文章

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

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

  2. ●BZOJ 3998 [TJOI2015]弦论

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3998题解: 后缀自动机. 当T=0时, 由于在后缀自动机上沿着trans转移,每个串都是互不 ...

  3. BZOJ 3998: [TJOI2015]弦论 后缀自动机 后缀自动机求第k小子串

    http://www.lydsy.com/JudgeOnline/problem.php?id=3998 后缀自动机应用的一个模板?需要对len进行一个排序之后再统计每个出现的数量,维护的是以该字符串 ...

  4. bzoj 3998: [TJOI2015]弦论

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

  5. bzoj 3998 [TJOI2015]弦论——后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3998 相同子串算多个的话,先求好 right ,然后求一个 sm 表示走到这个点之后有几种走 ...

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

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

  7. bzoj 3998: [TJOI2015]弦论【SA+二分||SAM】

    SA的话t==0直接预处理出每个后缀的不同串贡献二分即可,然后t==1就按字典序枚举后缀,然后跳右端点计算和当前后缀的前缀相同的子串个数,直到第k个 不过bzoj上会T #include<ios ...

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

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

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

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

随机推荐

  1. Servlet处理文件下载的编码问题,乱码。

    Servlet处理文件下载的编码问题,乱码. //处理文件名乱码问题 // 获得请求头中的User-Agent String agent = request.getHeader("User- ...

  2. What is the reason that a likelihood function is not a pdf?

    From: http://stats.stackexchange.com/questions/31238/what-is-the-reason-that-a-likelihood-function-i ...

  3. WeTest功能优化第3期:业内首创,有声音的云真机

    第3期功能优化目录 [云真机远程调试]音频同步传输实现测试有声 [兼容性测试报告]新增视频助力动态定位问题 [云真机远程调试]菜单栏优化助力机型选择 本期介绍的新功能,秉承创造用户需求的理念,在云真机 ...

  4. Object里面的方法

    object里面有12个方法,没写完,写一些部分代表 toString():输出对象的地址字符串(hashcode码) equals():用的是==,比较的是引用,在有些类里面是重写了这个方法的,重写 ...

  5. 负数取余/整除,Python和C语言的不同

    总结一句:Python中负数整除,是向负无穷取整,所以导致负数取余不对 在数学公式中,两种语言的表示算法都是一样的,都是: r=a-n*[a/n] 以上,r是余数,a是被除数,n是除数. 唯一不同点, ...

  6. 孤荷凌寒自学python第八十三天初次接触ocr配置tesseract环境

    孤荷凌寒自学python第八十三天初次接触ocr配置tesseract环境 (完整学习过程屏幕记录视频地址在文末) 学习Python我肯定不会错过图片文字的识别,当然更重要的是简单的验证码识别了,今天 ...

  7. ArcFaceDemo 第二版【C#】——视频人脸识别

    啥话不说,不用跪求,直接给下载地址:http://common.tenzont.com/comdll/arcface2demo.zip(话说附件的大小不限制,还是说我的文件太大,实际上确实有点大,60 ...

  8. Python字符串中的r前缀

    在Python中,如果字符串的前面有r/R前缀,那么,就会禁用转义符\的功能: >>>path = r'C:\new\text.dat' >>>pah 'C:\\n ...

  9. 浮点数(floating-point number)二进制存储格式

    定义 浮点数就是小数点位置不固定的数,也就是说与定点数不一样,浮点数的小数点后的小数位数可以是任意的,根据IEEE754-1985(也叫IEEE Standard for Binary Floatin ...

  10. windows编程常见数据类型

    windows编程常见数据类型, 总结一下方便查阅: 类型 对应指针 描述 ATOM . typedef WORD ATOM; BOOL LPBOOL 布尔类型,值要写成TRUE或FALSE,实际上是 ...