milk parttens

来源:互联网 发布:webservice数据丢失 编辑:程序博客网 时间:2024/06/03 21:31

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.

Input
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.
Output
Line 1: One integer, the length of the longest pattern which occurs at least K times
Sample Input
8 212323231

Sample Output

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;}


原创粉丝点击