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

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

lap 分析 using pro input body break 技術分享 最長

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

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

分析

後綴數組求出height(排名相鄰的兩個後綴的公共前綴),二分長度,在height中O(n)判斷。

時間復雜度O(nlogn)

直接二分+hash也可以,復雜度相同

code

技術分享圖片
 1 #include<cstdio>
 2
#include<cstring> 3 #include<algorithm> 4 5 using namespace std; 6 7 const int N = 50010; 8 9 int s[N]; 10 int t1[N],t2[N],c[N],sa[N],height[N],rank[N]; 11 int n,m = 130,k; 12 13 void get_sa() { 14 int i,p,*x = t1,*y = t2; 15 for (i=0; i<m; ++i) c[i] = 0; 16
for (i=0; i<n; ++i) x[i] = s[i],c[x[i]]++; 17 for (i=1; i<m; ++i) c[i] += c[i-1]; 18 for (i=n-1; i>=0; --i) sa[--c[x[i]]] = i; 19 for (int k=1; k<=n; k<<=1) { 20 p = 0; 21 for (i=n-k; i<n; ++i) y[p++] = i; 22 for (i=0; i<n; ++i) if(sa[i]>=k) y[p++]=sa[i]-k; 23 for (i=0; i<m; ++i) c[i] = 0; 24 for (i=0; i<n; ++i) c[ x[y[i]] ]++; 25 for (i=1; i<m; ++i) c[i] += c[i-1]; 26 for (i=n-1; i>=0; --i) sa[--c[ x[y[i]] ]] = y[i]; 27 swap(x,y); 28 p = 1; 29 x[sa[0]] = 0; 30 for (i=1; i<n; ++i) 31 x[sa[i]] = y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k] ? p-1:p++; 32 if (p>=n) break; 33 m = p; 34 } 35 } 36 void get_height() { 37 for (int i=0; i<n; ++i) rank[sa[i]] = i; 38 int k = 0; 39 height[0] = 0; 40 for (int i=0; i<n; ++i) { 41 if (!rank[i]) continue; 42 if (k) k--; 43 int j = sa[rank[i]-1]; 44 while (i+k<n && j+k<n && s[i+k]==s[j+k]) k++; 45 height[rank[i]] = k; 46 } 47 } 48 bool check(int x) { 49 int num = 0; 50 for (int i=0; i<n; ++i) { 51 if (height[i] >= x) { 52 num ++; 53 if (num == k-1) return true; 54 } 55 else num = 0; 56 } 57 return false; 58 } 59 60 int main () { 61 scanf("%d%d",&n,&k); 62 for (int i=0; i<n; ++i) scanf("%d",&s[i]); 63 get_sa(); 64 get_height(); 65 int L = 1,R = n,mid,ans; 66 while (L <= R) { 67 mid = (L + R) >> 1; 68 if (check(mid)) ans = mid,L = mid + 1; 69 else R = mid - 1; 70 } 71 printf("%d",ans); 72 return 0; 73 }
View Code

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