题意:求最长的可重叠的 K重复子串 的长度

考虑二分长度s,转化为验证性问题。

对SA进行分组。保证组内Height最小为s。这样在组内RMQ就可以任意了,因为RMQ一定是大于S的。

只要组内元素个数大于等于K就是可行解。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. struct SA{
  5. int str[];
  6. int x[],y[],u[],v[],r[],o[],hei[],m=,n;
  7.  
  8. int a[];
  9.  
  10. void build(int p,int l,int r){
  11. if(l==r) a[p]=hei[l];
  12. else build(p*,l,(l+r)/), build(p*+,(l+r)/+,r), a[p]=min(a[p*],a[p*+]);
  13. }
  14.  
  15. int query(int p,int l,int r,int ql,int qr){
  16. if(l>qr||r<ql) return 1e+;
  17. if(l>=ql&&r<=qr) return a[p];
  18. return min(query(p*,l,(l+r)/,ql,qr),query(p*+,(l+r)/+,r,ql,qr));
  19. }
  20.  
  21. void calc(){
  22. int i,j,k=;
  23. //for(i=1; i<=n; i++) r[x[i]]=i;
  24. for(i=; i<=n; hei[r[i++]]=k)
  25. for(k?k--:,j=x[r[i]-]; str[i+k]==str[j+k]; k++);
  26. }
  27.  
  28. int solve(){
  29. //n=strlen(str+1);
  30. //printf("len %d\n",n);
  31.  
  32. for(int i=;i<=n;i++) u[str[i]]++;
  33. for(int i=;i<=m;i++) u[i]+=u[i-];
  34. for(int i=n;i>=;i--) x[u[str[i]]--]=i;
  35. r[x[]]=;
  36. for(int i=;i<=n;i++) r[x[i]]=r[x[i-]]+((str[x[i]]-str[x[i-]])?:);
  37.  
  38. for(int l=;r[x[n]]<n;l<<=) {
  39. memset(u,,sizeof u);
  40. memset(v,,sizeof v);
  41. memcpy(o,r,sizeof r);
  42. for(int i=;i<=n;i++) u[r[i]]++, v[(i+l<=n)?r[i+l]:]++;
  43. for(int i=;i<=n;i++) u[i]+=u[i-], v[i]+=v[i-];
  44. for(int i=n;i>=;i--) y[v[(i+l<=n)?r[i+l]:]--]=i;
  45. for(int i=n;i>=;i--) x[u[r[y[i]]]--]=y[i];
  46. r[x[]]=;
  47. for(int i=;i<=n;i++)
  48. r[x[i]]=r[x[i-]]+((o[x[i]] != o[x[i-]]) || (((x[i]+l<=n)?o[x[i]+l]:) != ((x[i-]+l<=n)?o[x[i-]+l]:)));
  49. }
  50. calc();
  51. hei[]=;
  52. //build(1,1,n);
  53. }
  54.  
  55. int lcp(int pos1,int pos2){
  56. return query(,,n,min(r[pos1],r[pos2])+,max(r[pos1],r[pos2]));
  57. }
  58.  
  59. } sa;
  60.  
  61. int n,k;
  62.  
  63. int main(){
  64. cin>>n>>k;
  65. sa.n=n;
  66. for(int i=;i<=n;i++) cin>>sa.str[i];
  67. sa.solve();
  68. int l=,r=,ans=;
  69. while(r-l) {
  70. int s=(l+r)/,cnt=,mx=;
  71. for(int i=;i<=n+;i++)
  72. if(sa.hei[i]<s)
  73. mx=max(cnt,mx), cnt=;
  74. else cnt++;
  75. if(mx>=k) ans=max(ans,s), l=s+;
  76. else r=s;
  77. }
  78. cout<<ans<<endl;
  79.  
  80. }

USACO06DEC 牛奶模式的更多相关文章

  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. [Luogu2852][USACO06DEC]牛奶模式Milk Patterns

    Luogu 一句话题意 给出一个串,求至少出现了\(K\)次的子串的最长长度. sol 对这个串求后缀数组. 二分最长长度. 如果有\(K\)个不同后缀他们两两的\(lcp\)都\(>=mid\ ...

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

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

  6. [USACO06DEC] 牛奶模式Milk Patterns

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

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

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

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

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

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

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

随机推荐

  1. ELK学习003:Elasticsearch启动常见问题

    一.Caused by: java.lang.RuntimeException: can not run elasticsearch as root 这个错误,是因为使用root用户启动elastic ...

  2. springboot 查看H2数据库

    1  再application.properties文件中,添加 spring.h2.console.enabled=true 2 再浏览器中打开: http://localhost:8080/h2- ...

  3. Bash脚本编程学习笔记07:循环结构体

    本篇中涉及到算术运算,使用了$[]这种我未在官方手册中见到的用法,但是确实可用的,在此前的博文<Bash脚本编程学习笔记03:算术运算>中我有说明不要使用,不过自己忘记了.大家还是尽量使用 ...

  4. Uderstanding and using Pointers 读书笔记

    如何阅读指针? 从右向左读. 比如 const int *pci; 虚拟内存和虚拟内存地址是什么? 一个应用程序,在虚拟内存地址里也许是连续的,但是在物理内存里也许是分隔开来的. 虚拟内存和物理内存的 ...

  5. LeetCode 面试题22. 链表中倒数第k个节点

    题目链接:https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/ 输入一个链表,输出该链表中倒数第 ...

  6. set()和get()方法

    在很多程序中,都喜欢定义一个privata变量,然后为这个私有变量加上get(),set()方法.那为什么不直接定义一个public变量呢?这样做到底有什么好处和意义呢?难道真的仅仅只是为了代码规范? ...

  7. egg 提交数据 防csrf 攻击 配置

    await ctx.render('from',{csrf:this.ctx.csrf}); 或者 使用中间件 ctx.state.csrf = ctx.csrf;

  8. Node.js核心模块-fs文件系统

    fs是file-system的简写,文件系统的意思.在Node中如果想要进行文件操作,就必须引入fs这个核心模块. 引入 const fs = require('fs') fs.readFile(pa ...

  9. github访问过慢

    转:https://baijiahao.baidu.com/s?id=1608100091125662190&wfr=spider&for=pc https://www.cnblogs ...

  10. Centos 7 下安装 samba 服务

    yum install samba 配置文件在:/etc/samba/smb.conf [global] #添加下面这句 map to guest = Bad User #这个选项是保证匿名访问! # ...