这道题和UVa 12206一样,求至少重复出现k次的最长字串。

首先还是二分最长字串的长度len,然后以len为边界对height数组分段,如果有一段包含超过k个后缀则符合要求。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5.  
  6. const int maxn = + ;
  7. const int maxm = + ;
  8.  
  9. int s[maxn];
  10. int sa[maxn], height[maxn], rank[maxn];
  11. int t[maxn], t2[maxn], c[maxm];
  12. int n, k;
  13.  
  14. void build_sa(int m)
  15. {
  16. int i, *x = t, *y = t2;
  17. for(i = ; i < m; i++) c[i] = ;
  18. for(i = ; i < n; i++) c[x[i] = s[i]]++;
  19. for(i = ; i < m; i++) c[i] += c[i - ];
  20. for(i = n - ; i >= ; i--) sa[--c[x[i]]] = i;
  21. for(int k = ; k <= n; k <<= )
  22. {
  23. int p = ;
  24. for(i = n - k; i < n; i++) y[p++] = i;
  25. for(i = ; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
  26. for(i = ; i < m; i++) c[i] = ;
  27. for(i = ; i < n; i++) c[x[y[i]]]++;
  28. for(i = ; i < m; i++) c[i] += c[i - ];
  29. for(i = n - ; i >= ; i--) sa[--c[x[y[i]]]] = y[i];
  30. swap(x, y);
  31. p = ; x[sa[]] = ;
  32. for(i = ; i < n; i++)
  33. x[sa[i]] = y[sa[i]]==y[sa[i-]] && y[sa[i]+k]==y[sa[i-]+k] ? p - : p++;
  34. if(p >= n) break;
  35. m = p;
  36. }
  37. }
  38.  
  39. void build_height()
  40. {
  41. int i, j, k = ;
  42. for(i = ; i < n; i++) rank[sa[i]] = i;
  43. for(i = ; i < n; i++)
  44. {
  45. if(k) k--;
  46. j = sa[rank[i] - ];
  47. while(s[i + k] == s[j + k]) k++;
  48. height[rank[i]] = k;
  49. }
  50. }
  51.  
  52. bool ok(int len)
  53. {
  54. int cnt = ;
  55. for(int i = ; i < n; i++)
  56. {
  57. if(i == || height[i] < len) cnt = ;
  58. if(++cnt >= k) return true;
  59. }
  60. return false;
  61. }
  62.  
  63. int main()
  64. {
  65. //freopen("in.txt", "r", stdin);
  66.  
  67. scanf("%d%d", &n, &k);
  68. for(int i = ; i < n; i++)
  69. {
  70. scanf("%d", &s[i]);
  71. s[i]++;
  72. }
  73. s[n] = ;
  74. build_sa();
  75. build_height();
  76.  
  77. int L = , R = n;
  78. while(L < R)
  79. {
  80. int M = (L + R + ) / ;
  81. if(ok(M)) L = M;
  82. else R = M - ;
  83. }
  84.  
  85. printf("%d\n", L);
  86.  
  87. return ;
  88. }

代码君

POJ 3261 (后缀数组 二分) Milk Patterns的更多相关文章

  1. POJ 3261 后缀数组+二分

    思路: 论文题- 二分+对后缀分组 这块一开始不用基数排序 会更快的(其实区别不大) //By SiriusRen #include <cstdio> #include <cstri ...

  2. Milk Patterns POJ - 3261 后缀数组

    Farmer John has noticed that the quality of milk given by his cows varies from day to day. On furthe ...

  3. POJ 3261 后缀数组

    题目链接:http://poj.org/problem?id=3261 题意:约翰注意到奶牛产奶的之类是不断变化的,虽然他不能预测从当天到下一天的变化情况但是他知道变化是有规律的,牛奶的质量由一个整数 ...

  4. poj 3261 后缀数组 找反复出现k次的子串(子串能够重叠)

    题目:http://poj.org/problem?id=3261 仍然是后缀数组的典型应用----后缀数组+lcp+二分 做的蛮顺的,1A 可是大部分时间是在调试代码.由于模板的全局变量用混了,而自 ...

  5. poj 3261 后缀数组 可重叠的 k 次最长重复子串

    Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 16430   Accepted: 7252 Ca ...

  6. POJ 2774 后缀数组 || 二分+哈希

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 35607   Accepted: 14 ...

  7. POJ 1743 (后缀数组 二分) Musical Theme

    看来对height数组进行分段确实是个比较常用的技巧. 题意: 一个主题是可以变调的,也就是如果这个主题所有数字加上或者减少相同的数值,可以看做是相同的主题. 一个主题在原串中至少要出现两次,而且一定 ...

  8. [poj 3261]后缀数组+滑窗最小值

    题目链接:http://poj.org/problem?id=3261 这个是可以交叉的重复串,所以用height就可以了,但是题目说让重复k次以上,也就是直接做一个k-1长度的滑窗最小值,从这些最小 ...

  9. POJ - 3261 后缀数组 height应用

    题意:求最少重叠\(k\)次的重复子串的最大长度 子串长度问题依然是二分枚举,可以观察出重叠的一定是sa排序中连续的 之前想出一种判断要\(n^2\)的方法,没有考虑到后面肯定会连续出现的情况 (大概 ...

随机推荐

  1. Sublime Text 编辑器

    1.从http://www.sublimetext.com/2 下载Sublime Text 2编辑器. 2.安装Package Control 管理器,用于管理和安装插件包. 下载地址:https: ...

  2. NodeJS介绍

    1.概述: Node.js是基于Chrome JavaScript运行时建立的一个平台,实际上它是对Google Chrome V8引擎进行了封装,它主要用于创建快速的.可扩展的网络应用.Node.j ...

  3. HDU4831&&4832&&4834

    好久没打代码啦,今天lu一发百度之星,感觉还是学到不少东西的,写点收获. 第一题就是现在的HDU4831啦,题意很清楚,我一开始以为休息区也可以变为风景区,所以就不敢敲了,后来才得知数据里只会改风景区 ...

  4. CSS3实现页面的平滑过渡

    这是文件的css,全部文件的话请到Github下载:点击这里 @charset "UTF-8"; @font-face {font-family: 'iconfont'; src: ...

  5. iOS手势学习UIGestureRecognizer & cocos2d 手势推荐

    iOS手势学习UIGestureRecognizer & cocos2d 手势推荐 手势识别类型: UILongPressGestureRecognizer  // 长按UIPanGestur ...

  6. lintcode:数字组合III

    数字组合III 组给出两个整数n和k,返回从1......n中选出的k个数的组合. 您在真实的面试中是否遇到过这个题? Yes 样例 例如 n = 4 且 k = 2 返回的解为: [[2,4],[3 ...

  7. win8,定时任务添加(schtasks)

    win8,64位,通过CMD命令schtasks,添加定时任务 以下内容,均来自 schtasks /? 和 schtasks /create /? // 1.schtasks /create 的参数 ...

  8. Linux command: usermod -- 改变用户状态

    应用举例: 1. usermod -g newuser newuser force use GROUP as new primary group. 一般时候是默认的,也是必须的(不能更改).2. 指定 ...

  9. for语句中声明变量

    在C语言中,局部变量应该在函数的可执行语句之前定义,但在C++中变量可在任何语句位置定义,只要允许程序语句的地方,都允许定义变量. 在C99标准中C同C++一样允许在for循环语句中定义变量.并且这个 ...

  10. Struts2笔记——ONGL表达式语言

    OGNL是ObjectGraphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts 2框架使用OGNL作为默认的表达式语言. ----------- ...