题目地址:http://poj.org/problem?id=3261

题目:

Description

Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation, he discovered that although he can't predict the quality of milk from one day to the next, there are some regular patterns in the daily milk quality.

To perform a rigorous study, he has invented a complex classification scheme by which each milk sample is recorded as an integer between 0 and 1,000,000 inclusive, and has recorded data from a single cow over N (1 ≤ N ≤ 20,000) days. He wishes to find the longest pattern of samples which repeats identically at least K (2 ≤ K ≤ N) times. This may include overlapping patterns -- 1 2 3 2 3 2 3 1 repeats 2 3 2 3 twice, for example.

Help Farmer John by finding the longest repeating subsequence in the sequence of samples. It is guaranteed that at least one subsequence is repeated at least K times.

Input

Line 1: Two space-separated integers: N and K 
Lines 2..N+1: N integers, one per line, the quality of the milk on day i appears on the ith line.

Output

Line 1: One integer, the length of the longest pattern which occurs at least K times

Sample Input

8 2
1
2
3
2
3
2
3
1

Sample Output

4

思路:直接上后缀数组模板,跑个height数组。不过此时要注意两点:
  1.每个数的范围在0~1e6,所以要先离散化。不过此题数据较水,你可以不需要离散化,直接把字符最大值设为1e5就可以a了。不过直接开个1e6的数组应该也没事吧(没试过,待证实)
  2.这个数可能是0,所以要么把每个读取的数先+1,或者把ss[n]设为-1;
  然后二分答案,对height数组分组看符不符合答案。
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std; const int N = +;
int wa[N], wb[N], ws[N], wv[N];
int rank[N], height[N];
int sa[N],ss[N],n,k;
bool cmp(int r[], int a, int b, int l) {
return r[a] == r[b] && r[a+l] == r[b+l];
} void da(int r[], int sa[], int n, int m) {
int i, j, p, *x = wa, *y = wb;
for (i = ; i < m; ++i) ws[i] = ;
for (i = ; i < n; ++i) ws[x[i]=r[i]]++;
for (i = ; i < m; ++i) ws[i] += ws[i-];
for (i = n-; i >= ; --i) sa[--ws[x[i]]] = i;
for (j = , p = ; p < n; j *= , m = p) {
for (p = , i = n - j; i < n; ++i) y[p++] = i;
for (i = ; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
for (i = ; i < n; ++i) wv[i] = x[y[i]];
for (i = ; i < m; ++i) ws[i] = ;
for (i = ; i < n; ++i) ws[wv[i]]++;
for (i = ; i < m; ++i) ws[i] += ws[i-];
for (i = n-; i >= ; --i) sa[--ws[wv[i]]] = y[i];
for (swap(x, y), p = , x[sa[]] = , i = ; i < n; ++i)
x[sa[i]] = cmp(y, sa[i-], sa[i], j) ? p- : p++;
}
} void calheight(int r[], int sa[], int n) {
int i, j, k = ;
for (i = ; i <= n; ++i) rank[sa[i]] = i;
for (i = ; i < n; height[rank[i++]] = k)
for (k?k--:, j = sa[rank[i]-]; r[i+k] == r[j+k]; k++);
}
int check(int len)
{
int i=,cnt=;
while()
{
while(i<=n && height[i]>=len)
cnt++,i++;
if(cnt+>=k)return ;
if(i>=n)return ;
while(i <=n &&height[i]<len)
i++;
cnt=;
}
} int main()
{
scanf("%d%d",&n,&k);
for(int i=;i<n;i++)
scanf("%d",&ss[i]),ss[i]++;
ss[n]=;
da(ss,sa,n+,N);
calheight(ss,sa,n);
int l=,r=n,ans=,mid;
while(l<=r)
{
mid=(l+r)/;
if(check(mid))
l=mid+,ans=mid;
else
r=mid-;
}
printf("%d\n",ans);
return ;
}

poj3261Milk Patterns 后缀数组的更多相关文章

  1. POJ-3261-Milk Patterns(后缀数组)

    题意: 给定一个字符串,求至少出现k 次的最长重复子串,这k 个子串可以重叠. 分析: 先二分答案,然后将后缀分成若干组. 不同的是,这里要判断的是有没有一个组的后缀个数不小于k. 如果有,那么存在k ...

  2. [USACO06FEC]Milk Patterns --- 后缀数组

    [USACO06FEC]Milk Patterns 题目描述: Farmer John has noticed that the quality of milk given by his cows v ...

  3. POJ3261 Milks patterns(后缀数组)

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

  4. Poj 3261 Milk Patterns(后缀数组+二分答案)

    Milk Patterns Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk g ...

  5. poj3261 Milk Patterns 后缀数组求可重叠的k次最长重复子串

    题目链接:http://poj.org/problem?id=3261 思路: 后缀数组的很好的一道入门题目 先利用模板求出sa数组和height数组 然后二分答案(即对于可能出现的重复长度进行二分) ...

  6. BZOJ 1717 [USACO06DEC] Milk Patterns (后缀数组+二分)

    题目大意:求可重叠的相同子串数量至少是K的子串最长长度 洛谷传送门 依然是后缀数组+二分,先用后缀数组处理出height 每次二分出一个长度x,然后去验证,在排序的后缀串集合里,有没有连续数量多于K个 ...

  7. POJ 3261 Milk Patterns(后缀数组+单调队列)

    题意 找出出现k次的可重叠的最长子串的长度 题解 用后缀数组. 然后求出heigth数组. 跑单调队列就行了.找出每k个数中最小的数的最大值.就是个滑动窗口啊 (不知道为什么有人写二分,其实写啥都差不 ...

  8. POJ 3261 Milk Patterns ( 后缀数组 && 出现k次最长可重叠子串长度 )

    题意 : 给出一个长度为 N 的序列,再给出一个 K 要求求出出现了至少 K 次的最长可重叠子串的长度 分析 : 后缀数组套路题,思路是二分长度再对于每一个长度进行判断,判断过程就是对于 Height ...

  9. POJ 3261 Milk Patterns 后缀数组求 一个串种 最长可重复子串重复至少k次

    Milk Patterns   Description Farmer John has noticed that the quality of milk given by his cows varie ...

随机推荐

  1. 打开.py文件的方法

    用IDLE打开这个文件,然后按F5,系统就自动开始运行这个python程序,然后当前运行目录就跳转到这个目录了

  2. .net 编码常见问题

    问题一: windows service 启动时需要用死循环来控制程序,如果不开启异步,死循环会导致windows sevice 程序无法启动,代码情况如下 protected override vo ...

  3. 【转】不用程序mysql也可以查询今天、昨天、7天、近30天、本月、上一月的数据

    今天   select * from 表名 where to_days(时间字段名) = to_days(now());   昨天 SELECT * FROM 表名 WHERE TO_DAYS( NO ...

  4. Servlet Servlet是Java平台上的CGI技术

    Servlet Servlet是Java平台上的CGI技术.Servlet在服务器端运行,动态地生成Web页面.与传统的CGI和许多其它类似CGI的技术相比,Java Servlet具有更高的效率并更 ...

  5. java Thread方法解析: sleep join wait notify notifyAll

    转载自: sleep(),yield(),wait()区别详解:http://dylanxu.iteye.com/blog/1322066 join方法详解:http://www.open-open. ...

  6. js压缩 uglify

    grunt-contrib-uglify uglify是一个文件压缩插件,项目地址:https://github.com/gruntjs/grunt-contrib-uglify 本文将以一个DEMO ...

  7. jquery代码规范让代码越来越好看

    最近学了jQuery,感觉这个jQuery是真的挺不错的,果然像他说的那样,少些多做!刚一入手感觉真是不错.但是写多了,就会发现这个代码一行居然能写那么长.而且可读性还不好.  有幸自己买了一本锋利的 ...

  8. JavaScript------Throw和Try-Catch的使用

    function test() { try { var x = document.getElementById("demo").value; if (x == "&quo ...

  9. 一次显式GC导致的High CPU问题处理过程(转)

    项目现场反馈系统出现性能问题,具体表现为:所有的客户端响应极其卡顿. 第一反应推测,难道是DB层面出现阻塞?检查v$session会话状态及等待类型未见异常,应该可以排除DB层面原因导致的可能. 继续 ...

  10. 网站速度优化模块HttpCompressionModule

    为了优化网站的访问速度,准备采用HttpCompressionModule 6对传输数据进行压缩,下载了HttpCompressionModule 6 , 并按照示例程序中的web.config配置了 ...