Poj 3261 后缀数组

来源:互联网 发布:linux tail f 搜索 编辑:程序博客网 时间:2024/06/06 14:29

后缀数组真是强大,5s的题花了32ms

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn=20500;int s[maxn], s1[maxn];int id[maxn];int sa[maxn], t[maxn], t2[maxn], c[maxn], n, tim;int Rank[maxn], height[maxn];void build_sa(int m, int n){    int i, *x=t, *y=t2;    for(i=0;i<m;i++)c[i]=0;    for(i=0;i<n;i++)c[x[i]=s[i]]++;    for(i=1;i<m;i++)c[i]+=c[i-1];    for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i;    for(int k=1;k<=n;k<<=1){        int p=0;        for(i=n-k;i<n;i++)y[p++]=i;        for(i=0;i<n;i++)if(sa[i]>=k)y[p++]=sa[i]-k;        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]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;        if(p>=n)break;        m=p;    }}void geth(int n){    int i, j, k=0;    for(i=0;i<n;i++)Rank[sa[i]]=i;    for(i=0;i<n;i++){        if(k)k--;        if(Rank[i]==0)break;        j=sa[Rank[i]-1];        while(s[i+k]==s[j+k])k++;        height[Rank[i]]=k;    }}bool check(int mid, int n){    int i;    int st=0;    for(i=1;i<n;i++){        if(height[i]<mid){            if(i-st>=tim)return true;            st=i;        }    }    if(n-st>=tim)return true;    return false;}bool cmp(int x, int y){    return s[x]<s[y];}int main(){    while(~scanf("%d%d", &n, &tim)){        for(int i=0;i<n;i++)scanf("%d", &s[i]);        for(int i=0;i<n;i++)id[i]=i;        sort(id, id+n, cmp);        int p=0;        s1[id[0]]=++p;        for(int i=1;i<n;i++)s1[id[i]]=s[id[i]]==s[id[i-1]]?p:++p;        s1[n++]=0;        swap(s1, s);        build_sa(20005, n);        geth(n);        int l=1, r=n, ans=0;        while(l<=r){            if(r-l<=1){                if(check(r, n))ans=r;                else ans=l;                break;            }            int mid=(l+r)/2;            if(check(mid, n))l=mid;            else r=mid;        }        printf("%d\n", ans);    }}
0 0
原创粉丝点击