Luogu

一句话题意

给出一个串,求至少出现了\(K\)次的子串的最长长度。

sol

对这个串求后缀数组。

二分最长长度。

如果有\(K\)个不同后缀他们两两的\(lcp\)都\(>=mid\)

那么他们在\(SA\)中一定排在连续的一段区间,且两两之间的\(Height[i]>=mid\)

所以判断\(Height\)数组中是否存在长度大于等于\(K-1\)且数值全部大于等于\(mid\)的连续段。

code

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<queue>
  5. using namespace std;
  6. #define ll long long
  7. int gi()
  8. {
  9. int x=0,w=1;char ch=getchar();
  10. while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
  11. if (ch=='-') w=0,ch=getchar();
  12. while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
  13. return w?x:-x;
  14. }
  15. const int N = 1e6+10;
  16. int n,k,a[N],t[N],x[N],y[N],SA[N],Rank[N],Height[N];
  17. bool cmp(int i,int j,int k){return y[i]==y[j]&&y[i+k]==y[j+k];}
  18. void getSA()
  19. {
  20. int m=1e6+5;
  21. for (int i=1;i<=n;++i) ++t[x[i]=a[i]];
  22. for (int i=1;i<=m;++i) t[i]+=t[i-1];
  23. for (int i=n;i>=1;--i) SA[t[x[i]]--]=i;
  24. for (int k=1;k<=n;k<<=1)
  25. {
  26. int p=0;
  27. for (int i=0;i<=m;++i) y[i]=0;
  28. for (int i=n-k+1;i<=n;++i) y[++p]=i;
  29. for (int i=1;i<=n;++i) if (SA[i]>k) y[++p]=SA[i]-k;
  30. for (int i=0;i<=m;++i) t[i]=0;
  31. for (int i=1;i<=n;++i) ++t[x[y[i]]];
  32. for (int i=1;i<=m;++i) t[i]+=t[i-1];
  33. for (int i=n;i>=1;--i) SA[t[x[y[i]]]--]=y[i];
  34. swap(x,y);
  35. x[SA[1]]=p=1;
  36. for (int i=2;i<=n;++i) x[SA[i]]=cmp(SA[i],SA[i-1],k)?p:++p;
  37. if (p>=n) break;
  38. m=p;
  39. }
  40. for (int i=1;i<=n;++i) Rank[SA[i]]=i;
  41. for (int i=1,j=0;i<=n;++i)
  42. {
  43. if (j) --j;
  44. while (a[i+j]==a[SA[Rank[i]-1]+j]) ++j;
  45. Height[Rank[i]]=j;
  46. }
  47. }
  48. bool check(int mid)
  49. {
  50. int cnt=0;
  51. for (int i=1;i<=n;++i)
  52. {
  53. if (Height[i]>=mid) ++cnt;else cnt=0;
  54. if (cnt==k-1) return true;
  55. }
  56. return false;
  57. }
  58. int main()
  59. {
  60. n=gi();k=gi();
  61. for (int i=1;i<=n;++i) a[i]=gi()+1;
  62. getSA();
  63. int l=0,r=n;
  64. while (l<r)
  65. {
  66. int mid=l+r+1>>1;
  67. if (check(mid)) l=mid;
  68. else r=mid-1;
  69. }
  70. printf("%d\n",l);
  71. return 0;
  72. }

[Luogu2852][USACO06DEC]牛奶模式Milk Patterns的更多相关文章

  1. [洛谷P2852] [USACO06DEC]牛奶模式Milk Patterns

    洛谷题目链接:[USACO06DEC]牛奶模式Milk Patterns 题目描述 Farmer John has noticed that the quality of milk given by ...

  2. luogu P2852 [USACO06DEC]牛奶模式Milk Patterns 后缀数组 + Height数组 + 二分答案 + 扫描

    后缀数组有一个十分有趣的性质: $height[rk[i]] >= height[rk[i-1]] - 1$    Code: #include <bits/stdc++.h> #d ...

  3. 【后缀数组】【LuoguP2852】 [USACO06DEC]牛奶模式Milk Patterns

    题目链接 题目描述 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个"模式". J ...

  4. Luogu P2852 [USACO06DEC]牛奶模式Milk Patterns

    题目链接 \(Click\) \(Here\) 水题.利用\(Height\)的性质维护一个单调栈即可. #include <bits/stdc++.h> using namespace ...

  5. [USACO06DEC] 牛奶模式Milk Patterns

    题目链接:戳我 我们知道后缀数组的h数组记录的是后缀i和后缀i-1的最长公共前缀长度,后缀的前缀其实就是子串. 因为是可以重复出现的子串,所以我们只要计算哪些h数组的长度大于等于x即可.这一步操作我们 ...

  6. P2852 [USACO06DEC]牛奶模式Milk Patterns

    link 这是一道后缀匹配的模板题 我们只需要将height算出来 然后二分一下答案就可以了 #include<cstdio> #include<algorithm> #inc ...

  7. 洛谷P2852 牛奶模式Milk Patterns [USACO06DEC] 字符串

    正解:SA/二分+哈希 解题报告: 传送门! umm像这种子串的问题已经算是比较套路的了,,,?就后缀的公共前缀这样儿的嘛QwQ 所以可以先求个SA 然后现在考虑怎么判断一个长度为d的子串出现了k次? ...

  8. 2018.07.17 牛奶模式Milk Patterns(二分+hash)

    传送门 一道简单的字符串.这里收集了几种经典做法: SAM,不想写. 后缀数组+二分,不想写 后缀数组+单调队列,不想写 hash+二分,for循哈希,天下无敌!于是妥妥的hash 代码如下: #in ...

  9. USACO06DEC 牛奶模式

    题意:求最长的可重叠的 K重复子串 的长度 考虑二分长度s,转化为验证性问题. 对SA进行分组.保证组内Height最小为s.这样在组内RMQ就可以任意了,因为RMQ一定是大于S的. 只要组内元素个数 ...

随机推荐

  1. Java多线程应用总结

    一.基本方法 进程和线程一样,都是实现并发的一个基本单位.线程是比进程更小的执行单位,线程是在进程的基础上进行的进一步划分.所谓多线程,是指一个进程在执行过程中可以产生多个更小的程序单元,这些更小的单 ...

  2. UITableView 的使用小点

    1.系统默认的颜色设置//无色 cell.selectionStyle = UITableViewCellSelectionStyleNone; //蓝色 cell.selectionStyle = ...

  3. Go学习笔记03-附录

    第三部分 附录 A. 工具 1. 工具集 1.1 go build gcflags ldflags 更多参数: go tool 6g -h 或 [https://golang.org/cmd/gc/] ...

  4. phpstudy如何安装景安ssl证书 window下apache服务器网站https访问

    1. 下载景安免费证书 https://www.zzidc.com/help/helpDetail?id=555 2.文件解压上传至服务器,位置自己决定 3. 调整apache配置 景安原文链接:ht ...

  5. hihoCoder1319 岛屿周长 (bfs)

    思路:从给定坐标开始bfs,将所有联通点标记,然后把每个联通点的四个方向都判断一下,如果这个方向相邻的是一个非联通点说明需要把这条边实在最外围,即周长的一部分. AC代码 #include <s ...

  6. spring oauth2 ,spring security整合oauth2.0 JdbcTokenStore实现 解决url-pattern .do .action

    参考以下两个文章: http://www.cnblogs.com/0201zcr/p/5328847.html http://wwwcomy.iteye.com/blog/2230265 web.xm ...

  7. php的filesystem基本函数的学习(1)

    1.basename basename — 返回路径中的文件名部分 string basename ( string $path [, string $suffix ] ) 给出一个包含有指向一个文件 ...

  8. Quartz基本使用

    1.Quartz概述:简单的说就是java的一个定时任务的框架,没有那么复杂的解释,跟前端的定时器一样.在了解它之前,首先熟悉几个概念. 2.基本概念 2.1 Job:表示一个工作,要执行的具体内容. ...

  9. OSQA的配置

    1.安装Python,我安装的是python 2.7.3 2.安装setuptools 下载setuptools,并安装 安装好以后,在pyton2.7/scripts的路径下将会有easy_inst ...

  10. python基础 数据类型 判断语句

    python 类unix系统默认已经安装或使用源码包./confighuremakemake install python运行方法 通过交互式解释器 [root@room1pc01 ~]# pytho ...