[USACO06DEC] Milk Patterns
題目描述
Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation, he discovered that although he can‘t predict the quality of milk from one day to the next, there are some regular patterns in the daily milk quality.
To perform a rigorous study, he has invented a complex classification scheme by which each milk sample is recorded as an integer between 0 and 1,000,000 inclusive, and has recorded data from a single cow over N (1 ≤ N ≤ 20,000) days. He wishes to find the longest pattern of samples which repeats identically at least K (2 ≤ K ≤ N) times. This may include overlapping patterns -- 1 2 3 2 3 2 3 1 repeats 2 3 2 3 twice, for example.
Help Farmer John by finding the longest repeating subsequence in the sequence of samples. It is guaranteed that at least one subsequence is repeated at least K times.
農夫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。
輸入輸出格式
輸入格式:
Line 1: Two space-separated integers: N and K
Lines 2..N+1: N integers, one per line, the quality of the milk on day i appears on the ith line.
輸出格式:
Line 1: One integer, the length of the longest pattern which occurs at least K times
輸入輸出樣例
輸入樣例#1:8 2 1 2 3 2 3 2 3 1
輸出樣例#1:
4
(好像二分+HASH也可以做的樣子)
求出後綴數組和height之後,我們按height從大到小再排一次序,然後用並查集從前到後合並,如果某次合並後siz>=k了,那麽直接輸出當前的height即可。
#include<bits/stdc++.h> #define ll long long #define maxn 40005 using namespace std; int cc[maxn],n,m,k,r[maxn]; int sa[maxn],sax[maxn],sz[maxn]; int rank[maxn],rankx[maxn]; int sec[maxn],ans=0,p[maxn]; int s[maxn],a[maxn],ky,height[maxn]; inline bool cmp(int x,int y){ return height[x]>height[y]; } int ff(int x){ return (p[x]==x?x:(p[x]=ff(p[x]))); } inline void prework(){ for(int i=0;i<n;i++) cc[s[i]]++; for(int i=1;i<=n;i++) cc[i]+=cc[i-1]; for(int i=0;i<n;i++) sa[cc[s[i]]--]=i; for(int i=1;i<=n;i++){ rank[sa[i]]=i; if(i>1&&s[sa[i]]==s[sa[i-1]]) rank[sa[i]]=rank[sa[i-1]]; } int l=1; while(l<n){ memset(cc,0,sizeof(cc)); for(int i=0;i<n;i++) cc[sec[i]=rank[i+l]]++; for(int i=n-1;i>=0;i--) cc[i]+=cc[i+1]; for(int i=0;i<n;i++) sax[cc[sec[i]]--]=i; memset(cc,0,sizeof(cc)); for(int i=0;i<n;i++) cc[rank[i]]++; for(int i=1;i<=n;i++) cc[i]+=cc[i-1]; for(int i=1;i<=n;i++) sa[cc[rank[sax[i]]]--]=sax[i]; for(int i=1;i<=n;i++){ rankx[sa[i]]=i; if(i>1&&rank[sa[i]]==rank[sa[i-1]]&&sec[sa[i]]==sec[sa[i-1]]) rankx[sa[i]]=rankx[sa[i-1]]; } for(int i=0;i<n;i++) rank[i]=rankx[i]; l<<=1; } int now=0,j,mx; for(int i=0;i<n;i++){ if(rank[i]==1){ now=0,height[1]=0; continue; } if(now) now--; int j=sa[rank[i]-1],mx=max(i,j); while(mx+now<n&&s[i+now]==s[j+now]) now++; height[rank[i]]=now; } for(int i=1;i<=n;i++) r[i]=i,p[i]=i,sz[i]=1; sort(r+1,r+n+1,cmp); int u,v,fa,fb; for(int i=1;i<=n;i++){ u=r[i],v=r[i]-1; if(!v) continue; fa=ff(u),fb=ff(v); if(fa!=fb){ p[fa]=fb; sz[fb]+=sz[fa]; } if(sz[fb]>=k){ printf("%d\n",height[r[i]]); return; } } } int main(){ scanf("%d%d",&n,&k); for(int i=0;i<n;i++) scanf("%d",s+i),a[i+1]=s[i]; sort(a+1,a+n+1); ky=unique(a+1,a+n+1)-a-1; for(int i=0;i<n;i++) s[i]=lower_bound(a+1,a+n+1,s[i])-a; prework(); return 0; }
[USACO06DEC] Milk Patterns