Milk Patterns

Case Time Limit: 2000MS

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

Source

USACO 2006 December Gold

/*
后缀数组+二分答案.
求可重叠k次的最长重复子串.
比较暴力的做法,并没有离散化.
随便搞搞就行了..
*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define MAXN 1000010
using namespace std;
int n,K,m=1000002,ans,sa[MAXN],rank1[MAXN],c[MAXN],ht[MAXN],t1[MAXN],t2[MAXN],s[MAXN];
bool cmp(int *y,int a,int b,int k)
{
int a1=y[a],b1=y[b];
int a2=a+k>=n?-1:y[a+k];
int b2=b+k>=n?-1:y[b+k];
return a1==b1&&a2==b2;
}
void slovesa()
{
int *x=t1,*y=t2;
for(int i=0;i<m;i++) c[i]=0;
for(int i=0;i<n;i++) c[x[i]=s[i]]++;
for(int i=1;i<m;i++) c[i]+=c[i-1];
for(int i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
for(int k=1,p=0;k<=n;k<<=1,m=p,p=0)
{
for(int i=n-k;i<n;i++) y[p++]=i;
for(int i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(int i=0;i<m;i++) c[i]=0;
for(int i=0;i<n;i++) c[x[y[i]]]++;
for(int i=1;i<m;i++) c[i]+=c[i-1];
for(int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
swap(x,y),p=1,x[sa[0]]=0;
for(int i=0;i<n;i++)
{
if(cmp(y,sa[i-1],sa[i],k)) x[sa[i]]=p-1;
else x[sa[i]]=p++;
}
if(p>=n) break;
}
}
void sloveheight()
{
int k=0;
for(int i=0;i<n;i++) rank1[sa[i]]=i;
for(int i=0;i<n;ht[rank1[i++]]=k)
{
int j=sa[rank1[i]-1];
if(k) k--;
while(j+k<n&&i+k<n&&s[i+k]==s[j+k]) k++;
}
ht[0]=0;
}
bool check(int x)
{
int tot=1;bool flag=false;
for(int i=1;i<n;i++)
{
if(ht[i]>=x) tot++;
else tot=1;
if(tot>=K) return true;
}
return false;
}
void erfen(int l,int r)
{
int mid;
while(l<=r)
{
mid=(l+r)>>1;
if(check(mid)) ans=mid,l=mid+1;
else r=mid-1;
}
}
int main()
{
scanf("%d%d",&n,&K);
for(int i=0;i<n;i++) scanf("%d",&s[i]),s[i]++;
s[++n]=0;
slovesa(),sloveheight(),erfen(0,n);
printf("%d\n",ans);
return 0;
}

最新文章

  1. android shape的使用(转)
  2. Sublime Text 3 3126 注册码 + 下载地址
  3. Android开发学习总结(六)—— APK反编译
  4. PTPX中的report 选项
  5. Oracle存储过程返回游标实例详解
  6. ionic 嵌套view 的方法
  7. Javascript的动态运动(1)
  8. Descending Order
  9. 通过定时监听input框来实现onkeyup事件-
  10. selenium webdriver(1)---浏览器操作
  11. webconfig的设置节点几个说明
  12. oracle 随Linux系统启动自启动设置
  13. Android Studio Module疑问
  14. wifi定位原理
  15. Bower使用教程(限window)
  16. mpich2 下运行时出现“由于目标计算机积极拒绝,无法连接”的错误
  17. Ubuntu通过apt-get安装指定版本和查询软件源有多少个版本
  18. Ubuntu 15.10 下Redis Cluster使用
  19. PS中如何把图片颜色加到字体上去
  20. 打造利器Qt Creator:代码todo工具的使用

热门文章

  1. [洛谷P3227][HNOI2013]切糕
  2. Hadoop2-认识Hadoop大数据处理架构-单机部署
  3. C#精粹--协变和逆变
  4. 使用jQuery开发dialog对话框插件
  5. Java调用WebService方法总结(2)--JAX-WS调用WebService
  6. 浮动和渐变色,定位position,元素的层叠顺序
  7. CSSTab栏下划线跟随效果
  8. 解决cxf+springmvc发布的webservice,缺少types,portType和message标签的问题
  9. 朴素贝叶斯算法源码分析及代码实战【python sklearn/spark ML】
  10. django admin日期变为可以修改