1. 程式人生 > >[bzoj1717][Usaco2006 Dec]Milk Patterns 產奶的模式

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

stdin content 表示 clas 長度 不能 name 如果 n)

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

My Solution

打出後綴數組sa及數組height

做height的st表,枚舉height長度為k的區間內的最小值中的最大值

離線最值最愛st表

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 
 6 inline int
read(){ 7 char ch; 8 int re=0; 9 bool flag=0; 10 while((ch=getchar())!=-&&(ch<0||ch>9)); 11 ch==-?flag=1:re=ch-0; 12 while((ch=getchar())>=0&&ch<=9) re=re*10+ch-0; 13 return flag?-re:re; 14 } 15 16 const int maxn=20001,maxm=1e6;
17 int n,kkk; 18 int aa[maxn]; 19 int sa[maxn],t[maxn],t2[maxn],c[maxm]; 20 int height[maxn],rk[maxn]; 21 int m=1e6; 22 int stmin[maxn][16],mn[maxn]; 23 int ans=0; 24 25 void init(){ 26 n=read(),kkk=read(); 27 for(int i=0;i<n;i++) 28 aa[i]=read(); 29 n++; 30 } 31 32 void build_sa(){ 33 int i,*x=t,*y=t2; 34 for(i=0;i<m;i++) c[i]=0; 35 for(i=0;i<n;i++) c[x[i]=aa[i]]++; 36 for(i=0;i<m;i++) c[i]+=c[i-1]; 37 for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i; 38 for(int k=1;k<=n;k<<=1){ 39 int p=0; 40 for(i=n-k;i<n;i++) y[p++]=i; 41 for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k; 42 for(i=0;i<m;i++) c[i]=0; 43 for(i=0;i<n;i++) c[x[y[i]]]++; 44 for(i=0;i<m;i++) c[i]+=c[i-1]; 45 for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; 46 swap(x,y); 47 p=1; 48 x[sa[0]]=0; 49 for(i=1;i<n;i++) 50 x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++; 51 if(p>=n) break; 52 m=p; 53 } 54 } 55 56 void getHeight(){ 57 int i,j,k=0; 58 for(i=0;i<n;i++) rk[sa[i]]=i; 59 for(i=0;i<n;i++){ 60 if(k) k--; 61 j=sa[rk[i]-1]; 62 while(aa[i+k]==aa[j+k]) k++; 63 height[rk[i]]=k; 64 } 65 66 n--; 67 mn[0]=-1; 68 for(i=1;i<=n;i++){ 69 mn[i]=((i&(i-1))==0)?mn[i-1]+1:mn[i-1]; 70 stmin[i][0]=height[i]; 71 } 72 for(j=1;j<=mn[n];j++) 73 for(i=1;i+(1<<j)-1<=n;i++) 74 stmin[i][j]=min(stmin[i][j-1],stmin[i+(1<<(j-1))][j-1]); 75 } 76 77 int height_min(int left,int right){ 78 int k=mn[right-left+1]; 79 return min(stmin[left][k],stmin[right-(1<<k)+1][k]); 80 } 81 82 void solve(){ 83 kkk-=2; 84 for(int i=2;i<=n-kkk;i++){ 85 ans=max(ans,height_min(i,i+kkk)); 86 //printf("%d %d %d\n",i,i+kkk,height_min(i,i+kkk)); 87 } 88 printf("%d\n",ans); 89 } 90 91 int main(){ 92 //freopen("temp.in","r",stdin); 93 init(); 94 build_sa(); 95 getHeight(); 96 solve(); 97 return 0; 98 }

如果夢想有顏色,那一定是水藍色

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