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

xiaoxiao2021-02-28  142

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

Time Limit: 5 Sec   Memory Limit: 64 MB Submit: 1222   Solved: 660 [ 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

【分析】

后缀数组+二分答案

观察到如果i为可行长度,那么1~i一定都是可行长度(废话),所以我们可以二分最长长度,每次扫一遍height数组,如果满足连续K-1个height>=mid(二分的长度),那么mid就是一个可行解~

【代码】

//bzoj 1717 [Usaco2006 Dec]Milk Patterns 产奶的模式 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define M(a) memset(a,0,sizeof a) #define fo(i,j,k) for(i=j;i<=k;i++) using namespace std; const int mxn=20005; int n,m,K,len; char s[mxn]; int a[mxn],b[1000005],x[mxn],y[mxn],sa[mxn],rank[mxn],height[mxn]; inline bool comp(int i,int j,int l) { return y[i]==y[j]&&(i+l>len?-1:y[i+l])==(j+l>len?-1:y[j+l]); } inline void work() { int i,j,k,p;m=1000000; fo(i,0,m) b[i]=0; fo(i,1,len) b[x[i]=a[i]]++; fo(i,1,m) b[i]+=b[i-1]; for(i=len;i>=1;i--) sa[b[x[i]]--]=i; for(k=1;k<=len;k<<=1) { p=0; fo(i,len-k+1,len) y[++p]=i; fo(i,1,len) if(sa[i]>k) y[++p]=sa[i]-k; fo(i,0,m) b[i]=0; fo(i,1,len) b[x[y[i]]]++; fo(i,1,m) b[i]+=b[i-1]; for(i=len;i>=1;i--) sa[b[x[y[i]]]--]=y[i]; swap(x,y),p=2,x[sa[1]]=1; fo(i,2,len) x[sa[i]]=comp(sa[i-1],sa[i],k)?p-1:p++; if(p>len) break; m=p; } p=k=0; fo(i,1,len) rank[sa[i]]=i; for(i=1;i<=len;height[rank[i++]]=k) for(k?k--:0,j=sa[rank[i]-1];a[i+k]==a[j+k];k++); } inline bool ok(int mid) { int cnt=1,i,j; fo(i,2,len) { if(height[i]<mid) cnt=1; else cnt++; if(cnt>=K) return 1; } return 0; } int main() { int i,j; scanf("%d%d",&len,&K); fo(i,1,len) scanf("%d",&a[i]); work(); int l=1,r=len; while(l<r) { int mid=l+r+1>>1; if(ok(mid)) l=mid; else r=mid-1; } printf("%d\n",l); return 0; } //Have I found you? Flightless bird,jealous weeping. //or lost you? American mouth.Big pill,looming.

转载请注明原文地址: https://www.6miu.com/read-33003.html

最新回复(0)