POJ 3261 Milk Patterns 后缀数组

来源:互联网 发布:mac ssh目录 编辑:程序博客网 时间:2024/04/28 21:08

Description

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次的子串

也是一个后缀数组的板题。。。

首先建立一个后缀数组,然后把height求出来。

二分答案ans,也就是变成了是否有一组后缀的lcp都在ans以上且这些后缀的个数大于k


对了,我还有一点要说,明明题目中说了1000000,为什么那么多人还用计数排序呀!

神TM,你好歹也看看数据范围不要直接套版,不然加一个离散化也好呀,各种博客都没给说明,想都不想直接套版,AC了事写个鬼博客

虽然数据水你也不能这么干

因此我用的是归并排序,调用库函数stable_sort代替给第一关键字排序的计数排序,理由是这两个都是稳定的,可以保证不会打乱第二关键字的顺序

以上

#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int maxm=20010;int n,k,wa[maxm],wb[maxm],raw[maxm],sa[maxm],*x,*y,height[maxm],_rank[maxm];void da(),calheight();bool cmp(int* r,int a,int b,int L){return r[a]==r[b]&&r[a+L]==r[b+L];}bool cmp2(int a,int b){return x[a]<x[b];}bool judge(int mid);int main(){    ios_base::sync_with_stdio(false);    while(cin>>n>>k){        for(int i=0;i<n;++i)            cin>>raw[i];        raw[n++]=-1;        da();        calheight();        int le=1,ri=n-1;        while(ri>le+1){(judge((le+ri)>>1)?le:ri)=(le+ri)>>1;}        cout<<((le==ri||judge(ri))?ri:le)<<endl;    }    return 0;}void da(){    int i,j,p;    x=wa,y=wb;    for(i=0;i<n;++i)        sa[i]=i,x[i]=raw[i];    stable_sort(sa,sa+n,cmp2);    for(j=1,p=1;p<n;(j<<=1)){        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)sa[i]=y[i];        stable_sort(sa,sa+n,cmp2);        for(swap(x,y),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++;    }}void calheight(){    for(int i=0;i<n;++i)_rank[sa[i]]=i;    for(int i=0,j,k=0;i<n;height[_rank[i++]]=k)    for(k?k--:0,j=sa[_rank[i]-1];raw[i+k]==raw[j+k];++k);}bool judge(int mid){    int num=1;    for(int i=0;i<n;++i){        if(height[i]>=mid)            ++num;        else            num=1;        if(num>=k)            return true;    }    return false;}




0 0
原创粉丝点击