[BZOJ]1717 [Usaco2006 Dec]Milk Patterns 二分答案

来源:互联网 发布:centos 安装lamp环境 编辑:程序博客网 时间:2024/06/08 01:49

1717: [Usaco2006 Dec]Milk Patterns 产奶的模式

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 1283  Solved: 692
[Submit][Status][Discuss]

Description

农夫John发现他的奶牛产奶的质量一直在变动。经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠。我们称之为一个“模式”。 John的牛奶按质量可以被赋予一个0到1000000之间的数。并且John记录了N(1<=N<=20000)天的牛奶质量值。他想知道最长的出现了至少K(2<=K<=N)次的模式的长度。比如1 2 3 2 3 2 3 1 中 2 3 2 3出现了两次。当K=2时,这个长度为4。

Input

* Line 1: 两个整数 N,K。

* Lines 2..N+1: 每行一个整数表示当天的质量值。

Output

* Line 1: 一个整数:N天中最长的出现了至少K次的模式的长度

Sample Input

8 2
1
2
3
2
3
2
3
1

Sample Output

4

HINT

Source

Gold

[Submit][Status][Discuss]


HOME Back




这道题是论文上的题,作法是二分枚举长度再分组,若有一组成员个数超过题目所要求的k的话,就可以.二分性同上篇博客.

#include<stdio.h>#include<algorithm>using namespace std;const int maxn=20005;int wa[maxn],wb[maxn],rank[maxn],sa[maxn],height[maxn],w[maxn],ws[maxn],wv[maxn],tot;struct aa{    int v,num;}s[maxn];inline bool cmp1(aa a,aa b){return a.v<b.v;}inline bool cmp(int *r,int a,int b,int l){    return r[a]==r[b]&&r[a+l]==r[b+l];}inline const int read(){    register int f=1,x=0;register char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}return f*x;}inline void da(int *r,int n,int m){    int *x=wa,*y=wb;register int i,j,p=0;for(i=0;i<m;i++) ws[i]=0;for(i=0;i<n;i++) ws[x[i]=r[i]]++;for(i=1;i<m;i++) ws[i]+=ws[i-1];for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i;for(p=1,j=1;p<n;m=p,j*=2){    for(p=0,i=n-j;i<n;i++) y[p++]=i;for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;for(i=0;i<n;i++) wv[i]=x[y[i]];for(i=0;i<m;i++) ws[i]=0;for(i=0;i<n;i++) ws[wv[i]]++;for(i=1;i<m;i++) ws[i]+=ws[i-1];for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i];for(swap(x,y),x[sa[0]]=0,p=1,i=1;i<n;i++)x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;}}inline void calc_height(int *r,int n){    register int i,j,k=0;    for(i=1;i<=n;i++) rank[sa[i]]=i;for(i=0;i<n;height[rank[i++]]=k)for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);}inline bool check(int count,int n,int k){    int all=1;for(int i=1;i<n;i++){if(height[i]<count) all=0;    if(++all>=k) return true;}return false;}int main(){    int n=read(),k=read(),ans=0,pre=-1;for(register int i=0;i<n;i++) s[i].v=read(),s[i].num=i;    sort(s,s+n,cmp1);for(register int i=0;i<n;i++){    if(s[i].v>pre) pre=s[i].v,tot++;w[s[i].num]=tot;}w[n++]=0,da(w,n,n);calc_height(w,n-1);int lf=0,rg=n-1;while(lf<=rg){    int mid=(lf+rg)>>1;if(check(mid,n,k)) ans=mid,lf=mid+1;else rg=mid-1;}while(check(ans+1,n,k)) ans++;printf("%d\n",ans);}


阅读全文
0 0