您的位置:首页 > 其它

【BZOJ】【1717】【USACO 2006 Dec】Milk Patterns产奶的模式

2015-04-07 19:42 357 查看

后缀数组

  o(︶︿︶)o 唉傻逼了一下,忘了把后缀数组的字典范围改回20001,直接21交了上去,白白RE了两发……sigh

  既然要找出现了K次的子串嘛,那当然要用后缀数组了>_>(因为我太弱不会自动机&树)

  ok离散化后上后缀数组,求出height数组>_>然后用个……ST表= =?!

  O(n)地扫一遍所有的区间……看所有长度为k的里面最大的min(i,i+k-1)是多少(当然,k要减一,因为是K个子串的话对应的是K-1个串的LCP)

  水题还RE了两发→_→真是难过

/**************************************************************
Problem: 1717
User: Tunix
Language: C++
Result: Accepted
Time:40 ms
Memory:12224 kb
****************************************************************/

//BZOJ 1717
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
typedef long long LL;
inline int getint(){
int r=1,v=0; char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-')r=-1;
for(; isdigit(ch);ch=getchar()) v=v*10+ch-'0';
return r*v;
}
const int N=1e5+10,INF=~0u>>2;
/****************template***********************/
int a
,b
;
int n,k,SA
,rank
,height
,wa
,wb
,c
;
bool cmp(int *r,int a,int b,int l){
return r[a]==r[b] && r[a+l]==r[b+l];
}
void DA(int *s,int *sa,int n,int m){
int i,j,p,*x=wa,*y=wb;
rep(i,m) c[i]=0;
rep(i,n) c[x[i]=s[i]]++;
F(i,1,m-1) c[i]+=c[i-1];
D(i,n-1,0) sa[--c[x[i]]]=i;
for(j=1,p=0;p<n;j<<=1,m=p){
for(p=0,i=n-j;i<n;i++) y[p++]=i;
rep(i,n) if (sa[i]>=j) y[p++]=sa[i]-j;

rep(i,m) c[i]=0;
rep(i,n) c[x[y[i]]]++;
F(i,1,m-1) c[i]+=c[i-1];
D(i,n-1,0) sa[--c[x[y[i]]]]=y[i];
swap(x,y); p=1; x[sa[0]]=0;
F(i,1,n-1) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
}
}
void calheight(int *s,int *sa,int n){
int k=0;
F(i,1,n) rank[sa[i]]=i;
rep(i,n){
if (k) k--;
int j=sa[rank[i]-1];
while(s[i+k]==s[j+k]) k++;
height[rank[i]]=k;
}
}
int f
[20];
void ST(){
F(i,1,n) f[i][0]=height[i];
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
int query(int l,int r){
int k=log(r-l+1)/log(2);
return min(f[l][k],f[r-(1<<k)+1][k]);
}
int main(){
n=getint(); k=getint()-1;
rep(i,n) a[i]=b[i]=getint();
sort(b,b+n);
int num=unique(b,b+n)-b;
rep(i,n) a[i]=lower_bound(b,b+num,a[i])-b+2;
a
=0;
DA(a,SA,n+1,20001);
calheight(a,SA,n);
ST();
int ans=0;
F(i,1,n-k+1) ans=max(query(i,i+k-1),ans);
printf("%d\n",ans);
return 0;
}


View Code

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

Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 588 Solved: 331
[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]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: