后缀数组

来源:互联网 发布:windows whistler 2257 编辑:程序博客网 时间:2024/05/17 23:55

看了好久  总算有点懂了   A了俩道水题,把模版贴一下。。。


#include <cstdio>#include <cstring>#include <algorithm>#include <map>using namespace std;const int maxn = 100010;int s[maxn];int sa[maxn],wa[maxn],wb[maxn],ws[maxn];bool cmp(int *r,int a,int b,int k){    return r[a]==r[b]&&r[a+k]==r[b+k];}void da(int n,int m){    int *x=wa,*y=wb,*t,p;    for(int i=0;i<m;i++) ws[i]=0;    for(int i=0;i<n;i++) ws[x[i]=s[i]]++;    for(int i=1;i<m;i++) ws[i]+=ws[i-1];    for(int i=n-1;i>=0;i--) sa[--ws[x[i]]]=i;    for(int k=1;p<n;k<<=1,m=p)    {        p=0;        for(int i=n-k;i<n;i++) y[p++]=i;        for(int i=0;i<n;i++) if(sa[i]>=k) y[p++] = sa[i]-k;        for(int i=0;i<m;i++) ws[i]=0;        for(int i=0;i<n;i++) ws[x[y[i] ] ]++;        for(int i=1;i<m;i++) ws[i]+=ws[i-1];        for(int i=n-1;i>=0;i--) sa[--ws[x[y[i] ] ] ] = y[i];        int i;        for(t=x,x=y,y=t,x[sa[0]]=0,p=1,i=1;i<n;i++)            x[sa[i]] = cmp(y,sa[i-1],sa[i],k) ?p-1:p++;    }    return ;}int rank[maxn],height[maxn];void calheight(int n){    int k=0,j;    for(int i=1;i<=n;i++) rank[sa[i] ]=i;    for(int i=0;i<n;height[rank[i++]]=k)        for(k?k--:0,j=sa[rank[i]-1 ];s[i+k]==s[j+k];k++);    return ;}int main(){    int n,k;    while(~scanf("%d %d",&n,&k))    {        int m=1;        map<int,int>id;        for(int i=0;i<n;i++)        {            int x;            scanf("%d",&x);            if(!id[x]) id[x]=m++;            s[i]=id[x];        }        s[n]=0;        da(n+1,m);        calheight(n);        int l=1,r=n;        int ans=0;        while(l<=r)        {            m=(l+r)>>1;            int num=0;            for(int i=1;i<=n;i++)            {                if(height[i]>=m) num++;                else num=0;                if(num>=k-1) break;            }            if(num>=k-1)            {                ans=m;                l=m+1;            }            else r=m-1;        }        printf("%d\n",ans);    }}


原创粉丝点击