milk parttens
来源:互联网 发布:webservice数据丢失 编辑:程序博客网 时间:2024/06/03 21:31
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.
8 212323231
4
题意是找出重复次数大于等于K的最长的重复子串
首先重复次数大于等于K应该理解为连续K次 height[i]的长度都大于等于一个值
必须是连续的,因为height[i]表示的是第i个和第i-1个串的重复长度 如果中间断层了 一个是i 一个是j
是没有意义的 因为i跟i-1,j跟j-1重复的不是一样的子串。
然后二分枚举长度就可以了 具体在check注释那里
#include <iostream>#include<cstdio>#include<cstring>using namespace std;const int maxn=1000005;int wa[maxn],wb[maxn],wv[maxn],wss[maxn];int ran[maxn],height[maxn];int sa[maxn],r[maxn];char str[maxn*2];char str2[maxn];int cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l];}void da(int *r,int *sa,int n,int m){ int i,j,p,*x=wa,*y=wb,*t; for(i=0; i<m; i++) wss[i]=0; //cout<<"aaa"<<endl; for(i=0; i<n; i++) wss[x[i]=r[i]]++; //cout<<"bbbb"<<endl; for(i=1; i<m; i++) wss[i]+=wss[i-1]; //cout<<"cccccccc"<<endl; for(i=n-1; i>=0; i--) sa[--wss[x[i]]]=i; for(p=1,j=1; p<n; j*=2,m=p) { for(p=0,i=n-j; i<n; i++) y[p++]=i; for(i=0; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=0; i<n; i++) wv[i]=x[y[i]]; for(i=0; i<m; i++) wss[i]=0; for(i=0; i<n; i++) wss[wv[i]]++; for(i=1; i<m; i++) wss[i]+=wss[i-1]; for(i=n-1; i>=0; i--) sa[--wss[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1; i<n; i++ ) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } return ;}void calheight(int *r,int *sa,int n){ int i,j,k=0; for(i=1; i<=n; i++) ran[sa[i]]=i; for(i=0; i<n; height[ran[i++]]=k) for(k?k--:0,j=sa[ran[i]-1]; r[i+k]==r[j+k]; k++); return ;}int check(int len,int n,int k){ int count=1; for(int i=2;i<=n;i++) { if(height[i]>=len) { count++; if(count>=k) return 1; } else count=1; } return 0;}int main(){ int n,k; while(scanf("%d%d",&n,&k)!=-1) { int m=-1; for(int i=0;i<n;i++) { scanf("%d",&r[i]); r[i]++; m=max(m,r[i]); } r[n]=0; da(r,sa,n+1,1e5); calheight(r,sa,n); int l=1,r=n,mid,ans=1; while(l<=r) { int mid=(l+r)/2; if(check(mid,n,k)) { ans=mid; l=mid+1; } else r=mid-1; } printf("%d\n",ans); } return 0;}