POJ 3261 Milk Patterns 後綴數組

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 2
1
2
3
2
3
2
3
1

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




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章