3998: [TJOI2015]弦论

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 2152  Solved: 716
[Submit][Status][Discuss]

Description

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

Input

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

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

Output

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


T=1和上一题一样
T=2的话,每个状态不是代表一个子串,而是代表|Right|个子串,然后一样了
判断无解也可以直接与sum[root]比较哦
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <map>
  6. using namespace std;
  7. const int N=1e6+;
  8. inline int read(){
  9. char c=getchar();int x=,f=;
  10. while(c<''||c>''){if(c=='-')f=-; c=getchar();}
  11. while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
  12. return x*f;
  13. }
  14.  
  15. int n,Type,k;
  16. int c[N],a[N],d[N],sum[N];
  17. char s[N];
  18. struct State{
  19. int ch[],par,val;
  20. }t[N];
  21. int sz,root,last;
  22. inline int nw(int _){t[++sz].val=_;return sz;}
  23. inline void iniSAM(){sz=;root=last=nw();}
  24. void extend(int c){
  25. int p=last,np=nw(t[p].val+);d[np]=;
  26. for(;p&&!t[p].ch[c];p=t[p].par) t[p].ch[c]=np;
  27. if(!p) t[np].par=root;
  28. else{
  29. int q=t[p].ch[c];
  30. if(t[q].val==t[p].val+) t[np].par=q;
  31. else{
  32. int nq=nw(t[p].val+);
  33. memcpy(t[nq].ch,t[q].ch,sizeof(t[q].ch));
  34. t[nq].par=t[q].par;
  35. t[q].par=t[np].par=nq;
  36. for(;p&&t[p].ch[c]==q;p=t[p].par) t[p].ch[c]=nq;
  37. }
  38. }
  39. last=np;
  40. }
  41. void RadixSort(){
  42. for(int i=;i<=sz;i++) c[t[i].val]++;
  43. for(int i=;i<=n;i++) c[i]+=c[i-];
  44. for(int i=;i<=sz;i++) a[c[t[i].val]--]=i;
  45. }
  46. void dp(){
  47. RadixSort();
  48. for(int i=sz;i>=;i--){
  49. int u=a[i];
  50. if(Type==) d[t[u].par]+=d[u];
  51. else d[u]=;
  52. }
  53. for(int i=sz;i>=;i--){
  54. int u=a[i];
  55. sum[u]=d[u];
  56. for(int j=;j<;j++) sum[u]+=sum[t[u].ch[j]];
  57. }
  58. }
  59. int ans[N],p;
  60. void kth(int k){
  61. int u=root;
  62. while(k>){
  63. for(int i=;i<;i++) if(t[u].ch[i]){
  64. int v=t[u].ch[i];
  65. if(sum[v]>=k) {ans[++p]=i;k-=d[v];u=v;break;}
  66. else k-=sum[v];
  67. }
  68. }
  69. }
  70. int main(){
  71. freopen("in","r",stdin);
  72. scanf("%s",s+);
  73. n=strlen(s+);
  74. iniSAM();
  75. for(int i=;i<=n;i++) extend(s[i]-'a');
  76. Type=read();k=read();
  77. dp();
  78. if(sum[]<k) puts("-1");
  79. else{
  80. kth(k);
  81. for(int i=;i<=p;i++) putchar(ans[i]+'a');
  82. }
  83. }
 
 
 

BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

    传送门 解题思路 \(T=0\)时就和SP7258一样,\(T=1\)时其实也差不多,只不过要把每个点原来是\(1\)的权值改为\(Right\)集合的大小. 代码 #include<iostr ...

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

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

  8. ●BZOJ 3998 [TJOI2015]弦论

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

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

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

随机推荐

  1. c++(选择排序)

    选择排序是和冒泡排序差不多的一种排序.和冒泡排序交换相连数据不一样的是,选择排序只有在确定了最小的数据之后,才会发生交换.怎么交换呢?我们可以以下面一组数据作为测试: 2, 1, 5, 4, 9 第一 ...

  2. TI-RTOS 之 PWM

    TI-RTOS 之 PWM CC1310 有4个定时器,8个PWM通道,在TI-RTOS它的驱动是写好的,引用时需要包含 PWM.h头文件即可. 一般是任务主体之前,或者主函数进行初始化. Board ...

  3. Python 使用 virtualenvwrapper 安装虚拟环境

    装载于https://www.jianshu.com/p/9f47a9801329 Python 使用 virtualenvwrapper 安装虚拟环境 Tim_Lee 关注 2017.05.04 2 ...

  4. java的运算符和表达式

    )1.算数运算符:java中常用的算术运算符除了 +.-.*./之外,还有%(取余).++(自增).--(自减). )1.1%(取余):可适用于整数,char,浮点数的取余中.在取余中,如果进行运算的 ...

  5. O2O网站

    编辑 020是新型的网络营销模式,O2O即Online To Offline,线下销售与服务通过线上推广来揽客,消费者可以通过线上来筛选需求,在线预订.结算,甚至可以灵活地进行线上预订,线下交易.消费 ...

  6. dede列表标签list:应用大全 {dede:list}

    http://syizq.blog.163.com/blog/static/435700372011616115826329/ 标签名称: list 功能说明: 表示列表模板里的分页内容列表 适用范围 ...

  7. Java中的对象Object方法之---wait()和notifiy()

    这一篇咋们继续,接着来介绍wait()和notify()方法,我们都知道这两个方法和之前介绍的方法不太一样,那就是这两个方法是对象Object上的,不属于Thread类上的.我们也知道这两个方法是实现 ...

  8. Spring Boot实战:拦截器与过滤器

    一.拦截器与过滤器 在讲Spring boot之前,我们先了解一下过滤器和拦截器.这两者在功能方面很类似,但是在具体技术实现方面,差距还是比较大的.在分析两者的区别之前,我们先理解一下AOP的概念,A ...

  9. docker结合jenkins、gitlab实现.netcore的持续集成实践

    本文的目标是实现下图基于ASP NET Core的实践 运行环境 Cent OS 7 vs code .net core cmder 运行docker,设置docker镜像加速器,不然国内下载imag ...

  10. Traits技法

    扮演"特性萃取机"角色,萃取各个迭代器的特性(迭代器的相应类型) 模板特例化:提供一份template定义式,而其本身仍为templatization 通过class templa ...