我真的是。。调了一百年。。

傻逼的人生。。

而且这题好像可以用sam做哎!我Y出了一个奇怪的办法。。

好吧sam是不能做这题的。搞错了。

说说后缀数组好了。。

搞后缀数组

然后我们要二分一个子串,判断是否有一种划分方法,满足划分出来的所有串的最大子串不超过这个串。

二分是第now个后缀

二分第now个多长的前缀

————确定了一个子串

首先,这题具有单调性,而且是求最大串最小,所以我们可以二分答案串。

  怎么二分答案串呢,我们不是已经用后缀数组求出了sa数组吗,sa数组表示的串是排过序的,其中每个后缀的前缀子串大小按长度的递增而递增,所以可以在sa数组里面二分。(我是先二分后缀,再二分长度)
  然后是判断,怎么判断是不是可以划分成至多k个串使他们都不超过二分串。
  还是在sa上做。
  如果他的sa位置小于mid,那么不用管,因为它怎么样都是小于二分串的。
  如果他的sa位置大于等于mid,而且他跟二分串没有LCP,那么这个二分一定没有答案,因为最小二分都使他不符合。
  除此之外,求出sa位置大于等于mid的所有串跟二分串的LCP,在sa[i]~sa[i]+lcp-1的位置上一定要至少打一个标记,因为不打标记它就会比二分串大了。
  
  所以最后我们会得到很多个区间,在这些区间里面至多打k-1个标记,使得每个区间中有含有一个标记。
 
  转化成了这样,就很容易做了。貌似是smg区间覆盖之类的问题。排个序,去个重,判断+累加一下就可以了。
 
  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<iostream>
  6. #include<algorithm>
  7. using namespace std;
  8.  
  9. const int N=,Inf=(int)1e9;
  10. int K,n,cl,ed,r[N],h[N],t[N],rk[N],Rs[N],sa[N],y[N],wr[N];
  11. char c[N];
  12.  
  13. int minn(int x,int y){return x<y ? x:y;}
  14.  
  15. void get_sa(int m)
  16. {
  17. for(int i=;i<=cl;i++) rk[i]=c[i]-'a'+;
  18. for(int i=;i<=m;i++) Rs[i]=;
  19. for(int i=;i<=cl;i++) Rs[rk[i]]++;
  20. for(int i=;i<=m;i++) Rs[i]+=Rs[i-];
  21. for(int i=cl;i>=;i--) sa[Rs[rk[i]]--]=i;//debug
  22.  
  23. int ln=,p=;
  24. while(p<cl)
  25. {
  26. int k=;
  27. for(int i=cl-ln+;i<=cl;i++) y[++k]=i;
  28. for(int i=;i<=cl;i++)
  29. if(sa[i]>ln) y[++k]=sa[i]-ln;
  30. for(int i=;i<=cl;i++) wr[i]=rk[y[i]];
  31.  
  32. for(int i=;i<=m;i++) Rs[i]=;
  33. for(int i=;i<=cl;i++) Rs[wr[i]]++;
  34. for(int i=;i<=m;i++) Rs[i]+=Rs[i-];
  35. for(int i=cl;i>=;i--) sa[Rs[wr[i]]--]=y[i];//debug
  36.  
  37. for(int i=;i<=cl;i++) wr[i]=rk[i];
  38. for(int i=cl+;i<=cl+ln;i++) wr[i]=;
  39. rk[sa[]]=;
  40. p=;
  41. for(int i=;i<=cl;i++)
  42. {
  43. if(wr[sa[i]]!=wr[sa[i-]] || wr[sa[i]+ln]!=wr[sa[i-]+ln]) p++;
  44. rk[sa[i]]=p;
  45. }
  46. ln*=;m=p;
  47. // for(int i=1;i<=cl;i++) printf("%d ",rk[i]);printf("\n");
  48. // for(int i=1;i<=cl;i++) printf("%d ",sa[i]);printf("\n");
  49. }
  50. sa[]=rk[]=;
  51. }
  52.  
  53. void get_h()
  54. {
  55. int k=;
  56. for(int i=;i<=cl;i++) if(rk[i]!=)
  57. {
  58. int j=sa[rk[i]-];
  59. if(k) k--;
  60. while(c[i+k]==c[j+k] && i+k<=cl && j+k<=cl) k++;
  61. h[rk[i]]=k;
  62. }
  63. h[]=;
  64. }
  65.  
  66. bool ok(int ll,int rr)
  67. {
  68. int k=rr-ll+;
  69. memset(t,,sizeof(t));
  70. memset(r,,sizeof(r));
  71. for(int i=rk[ll];i<=cl;i++)
  72. {
  73. if(i!=rk[ll]) k=minn(k,h[i]);
  74. else if(rr==cl) continue;
  75. if(k==) return ;
  76. if(t[sa[i]]== || sa[i]+k-<t[sa[i]]) t[sa[i]]=sa[i]+k-;
  77. }
  78. int pl=,pr=,cut,ans;
  79. for(int i=cl;i>=;i--)
  80. {
  81. if(!t[i]) continue;
  82. if(!pr) {pr=i;continue;}
  83. if(pr<=t[i]) t[i]=;
  84. pr=t[i];
  85. }
  86. for(int i=;i<=cl;i++) if(t[i]) r[t[i]]=i;
  87. pl=,pr=,cut=,ans=;
  88. for(int i=cl;i>=;i--)
  89. {
  90. if(!r[i]) continue;
  91. if(!pl) {pl=r[i],pr=i;cut=r[i];ans++;continue;}
  92. if(i<pl) cut=r[i],ans++;
  93. if(pl<=i && i<=pr)
  94. {
  95. if(!(cut>=r[i] && cut<=i)) cut=r[i],ans++;
  96. }
  97. pl=r[i],pr=i;
  98. }
  99. if(ans<=K-) return ;
  100. return ;
  101. }
  102.  
  103. int check(int now)
  104. {
  105. int ll=sa[now]+h[now],rr=cl,mid;
  106. while(ll<=rr)
  107. {
  108. mid=(ll+rr)/;
  109. if(ok(sa[now],mid))
  110. {
  111. rr=mid;
  112. if(ll==rr) return ll;
  113. }
  114. else ll=mid+;
  115. }
  116. if(ll<=rr) return ll;
  117. return ;
  118. }
  119.  
  120. int main()
  121. {
  122. // freopen("a.in","r",stdin);
  123. freopen("magic.in","r",stdin);
  124. freopen("magic.out","w",stdout);
  125. scanf("%d",&K);
  126. scanf("%s",c+);
  127. cl=strlen(c+);
  128. get_sa();
  129. get_h();
  130. int ll=,rr=cl,mid,now;
  131. while(ll<rr)
  132. {
  133. mid=(ll+rr)/;
  134. now=check(mid);
  135. if(now) rr=mid,ed=now;
  136. else ll=mid+;
  137. }
  138. if(ll)
  139. {
  140. for(int i=sa[ll];i<=ed;i++) printf("%c",c[i]);printf("\n");
  141. }
  142. return ;
  143. }

贴一下代码啦。

【bzoj4310/hdu5030-跳蚤】后缀数组的更多相关文章

  1. 【BZOJ-4310】跳蚤 后缀数组 + ST表 + 二分

    4310: 跳蚤 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 180  Solved: 83[Submit][Status][Discuss] De ...

  2. 【bzoj4310】跳蚤 后缀数组+二分

    题目描述 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究. 首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典序最大的那一个 ...

  3. [BZOJ4310] 跳蚤 - 后缀数组,二分,ST表

    [BZOJ4310] 跳蚤 Description 首先,他会把串分成不超过 \(k\) 个子串,然后对于每个子串 \(S\) ,他会从 \(S\) 的所有子串中选择字典序最大的那一个,并在选出来的 ...

  4. bzoj 4310 跳蚤 —— 后缀数组+二分答案+贪心

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4310 二分答案——在本质不同的子串中二分答案! 如果二分到的子串位置是 st,考虑何时必须分 ...

  5. bzoj 4310 跳蚤——后缀数组+二分答案+贪心

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4310 答案有单调性? 二分出来一个子串,判断的时候需要满足那些字典序比它大的子串都不出现! ...

  6. BZOJ4310: 跳蚤 【后缀数组+二分】

    Description 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究.首先,他会把串 分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典 ...

  7. 跳蚤[BZOJ4310](后缀数组+二分答案传判定)

    不知道后缀数组的请退回去! 题面: 题目描述 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究.首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S ...

  8. bzoj 4310 跳蚤 二分答案+后缀数组/后缀树

    题目大意 给定\(k\)和长度\(\le10^5\)的串S 把串分成不超过\(k\)个子串,然后对于每个子串\(s\),他会从\(s\)的所有子串中选择字典序最大的那一个,并在选出来的\(k\)个子串 ...

  9. 后缀数组 hash求LCP BZOJ 4310: 跳蚤

    后缀数组的题博客里没放进去过..所以挖了一题写写 充实下博客 顺便留作板子.. 一个字符串S中 内容不同的子串 有 sigma{n-sa[i]+1-h[i]}   (噢 这里的h[]就是大家熟知的he ...

随机推荐

  1. 你真的了解React吗

    https://zhufengzhufeng.github.io/zhufengreact/index.html#t21.%E4%BB%80%E4%B9%88%E6%98%AFReact?

  2. 云计算之路-阿里云上:受够了OCS,改用ECS+Couchbase跑缓存

    当今天早上在日志中发现这样的错误之后,对阿里云OCS(mecached缓存服务)的积怨倾泻而出. 2014-06-08 07:15:56,078 [ERROR] Enyim.Caching.Memca ...

  3. jmeter更改启动编码设置

    项目中碰到这样的问题,在eclipse经过utf-8转码的代码,能正常运行,放到了jmeter里面运行,就是乱码,如下: String s = "乔佳飞"; String ss = ...

  4. Python升级3.6 强力Django+Xadmin打造在线教育平台

    第 1 章 课程介绍 1-1 项目演示和课程介绍: 第 2 章 Windows下搭建开发环境 2-1 Pycharm.Navicat和Python解释器的安装: Pycharmhttp://www.j ...

  5. 容器基础(三): 使用Cgroups进行资源限制

    Linux Cgroups Linux Cgroups 是 Linux 内核中用来为进程设置资源限制的一个重要功能. Cgroups将进程进行分组, 然后对这一组进程进行统一的资源监控和限制.Cgro ...

  6. 多文件上传 input 的multiple 属性

    一.上传多张图片并且预览 HTML: <div class="container"> <label>请选择一个图像文件:</label> < ...

  7. 面试题中经常遇到的SQL题:删除重复数据,保留其中一条

    如题,解决思路如下: 1.首先我们需要找出拥有重复数据的记录 ---以name字段分组 select Name,COUNT(Name) as [count] from Permission group ...

  8. 【python爬虫】对喜马拉雅上一个专辑的音频进行爬取并保存到本地

    >>>内容基本框架: 1.爬虫目的 2.爬取过程 3.代码实现 4.爬取结果  >>>实验环境: python3.6版本,pycharm,电脑可上网. [一 爬虫目 ...

  9. 延迟加载(Lazyload)三种实现方式

    定义:延迟加载也称为惰性加载,即在长网页中延迟加载图像.用户滚动到它们之前,视口外的图像不会加载.这与图像预加载相反,在长网页上使用延迟加载将使网页加载更快.在某些情况下,它还可以帮助减少服务器负载. ...

  10. 安装elasticsearch-1.7.1及中文IK和近义词配置

    安装elasticsearch及中文IK和近义词配置 https://www.cnblogs.com/yjf512/p/4789239.html 安装elasticsearch及中文IK和近义词配置 ...