您的位置:首页 > 其它

[bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式

2017-07-29 10:43 471 查看

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

Time Limit: 5 Sec  Memory Limit: 64 MB

[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

没有什么好讲的,写错了就是写错了
模板都打错了
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N = 20000 + 5;
const int M = 1000000 + 5;
int n,k,ans,m=1000001;
int s
,sa
,height
,c[M],x
,y
,rank
;
void build_sa(){
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; k <= n; k <<= 1 ){
int  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 = 1; i < n; i++ )
x[sa[i]] = ((y[sa[i]]==y[sa[i-1]])&&(sa[i-1]+k>=n?-1:y[sa[i-1]+k])==(sa[i]+k>=n?-1:y[sa[i]+k]))?p-1:p++;
if( p >= n ) return;
m = p;
}
}
void build_height(){
for( int i = 0; i < n; i++ ) rank[sa[i]] = i;
int k = 0; height[0] = 0;
for( int i = 0; i < n; i++ ){
if( !rank[i] ) continue;
if( k ) k--;
int j = sa[rank[i]-1];
while( i+k<n && j+k<n && s[i+k] == s[j+k] ) k++;
height[rank[i]] = k;
}
}
bool check( int x ){
int cnt = 0;
for( int i =0; i < n; i++ )
if( height[i] >= x ){
cnt++;
if( cnt == k-1 ) return true;
}
else cnt=0;
return false;
}
int main(){
scanf("%d%d", &n, &k);
for( int i = 0; i < n; i++ ) scanf("%d", &s[i]);
build_sa(); build_height();
int l = 1, r = n, ans = 0;
while( l <= r ){
int mid = (l+r)>>1;
if( check(mid) ) ans = mid, l = mid+1;
else r = mid-1;
}
printf("%d", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: