poj3261(後綴數組+二分+kuangbin模版注意問題)



#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
const int maxn = 2000000+1000;
int t1[maxn],t2[maxn],c[maxn*10];

bool cmp(int *r, int a, int b, int l){
    return r[a]==r[b]&&r[a+l]==r[b+l];
}
int len = 0;

void da(int str[], int sa[], int rank[], int height[], int n, int m){
    n++;
    int i, j, p, *x = t1, *y = t2;
    for(int i = 0;i<m;++i)c[i] = 0;
    for(int i = 0;i<n;++i)c[x[i]=str[i]]++;
    for(int i = 1;i<m;++i)c[i]+=c[i-1];
    for(int i =n-1;i>=0;i--)sa[--c[x[i]]] = i;
    for(j = 1;j<=n;j<<=1){
        p = 0;
        for(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<m;++i)c[i] = 0;
        for(i = 0;i<n;++i)c[x[y[i]]]++;
        for(i = 1;i<m;++i)c[i]+=c[i-1];
        for(i = n-1;i>=0;--i)sa[--c[x[y[i]]]]  =y[i];
        swap(x,y);
        p = 1;
        x[sa[0]] = 0;
        for(i = 1;i<n;++i)
            x[sa[i]] = cmp(y,sa[i-1],sa[i],j)?p-1:p++;
        if(p>=n)break;
        m = p;

    }
    int k = 0;
    n--;
    for(i = 0;i<=n;++i){
        rank[sa[i]] = i;
    }
    for(i = 0;i<n;++i){
        if(k)k--;
        j = sa[rank[i]-1];
        while(str[i+k]==str[j+k]){
            k++;
        }
        height[rank[i]] = k;
    }
}

int Rank[maxn],height[maxn];
char str[maxn];
int r[maxn],sa[maxn];
int s[maxn];
int id[maxn];
int n,k;
const int INF = 0x3f3f3f3f;
int check(int x,int k){
    int cnt = 1;
    for(int i = 2;i<=n;++i){
        if(height[i]>=x){
            cnt++;
            if(cnt>=k)return true;
        }
        else{
            cnt = 1;
        }

    }
    return false;
}
int main(){

    scanf("%d%d",&n,&k);
    int maxs = 0;
    for(int i = 0;i<n;++i){
        scanf("%d",&r[i]);
        r[i]++;
        maxs = max(r[i],maxs);
    }
    r[n] = 0;//r[n]一定要設置一個和所有字符都不一樣的字符 不然後綴排序會死循環
    da(r,sa,Rank,height,n,maxs+1);//這裏不用n+1,一定要是n 而且最後一個參數必須比最大值大
    int l = 1;
    int r = n;
    int ans = 1;

    while(l<=r){
        int mid = (l+r)>>1;
        if(check(mid,k)){
            ans = mid;
            l = mid+1;
        }
        else{
            r = mid-1;
        }
    }
    printf("%d\n",ans);

}

 

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