Sa求法

来源:互联网 发布:aape淘宝正品店有哪些 编辑:程序博客网 时间:2024/04/28 21:01
#include <iostream>#include <cstdio>#include <math.h>#include <algorithm>#include <string.h>using namespace std;const int MAXN=20010;int t1[MAXN],t2[MAXN],c[MAXN];bool cmp(int *r,int a,int b,int l){    return r[a]==r[b] && r[a+l]== r[b+l];}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 (int j=1;j<=n;j <<=1)    {        p=0;        for (int i=n-j; i<n ; i++) y[p++] =i;        for (int i=0; i<n; i++)            if (sa[i]>=j) y[p++]=sa[i]-j;        for (int i=0; i<m; i++)            c[i]=0;        for (int i=0; i<n; i++)            c[x[y[i]]]++;        for (int i=1; i<m; i++)            c[i]+=c[i-1];        for (int i=n-1;i>=0;i--)            sa[--c[x[y[i]]]] = y[i];        swap(x,y);        p=1; x[sa[0]] = 0;        for (int 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 (int i=0;i<=n;i++)        Rank[sa[i]]=i;    for (int 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];int RMQ[MAXN];int mm[MAXN];int best[20][MAXN];void initRMQ(int n){    mm[0]=-1;    for (int i=1;i<=n;i++)        mm[i] = ((i&(i-1)) == 0) ? mm[i-1]+1:mm[i-1];    for (int i=1;i<=n;i++)        best[0][i]=i;    for (int i=1;i<=mm[n];i++)        for (int j=1;j+(1<<i)-1<=n;j++)    {        int a=best[i-1][j];        int b=best[i-1][j+(1<<(i-1))];        if (RMQ[a]<RMQ[b]) best[i][j]=a;        else best[i][j]=b;    }}int askRMQ(int a,int b){    int t;    t=mm[b-a+1];    b-=(1<<t)-1;    a=best[t][a];    b=best[t][b];    return RMQ[a]<RMQ[b]?a:b;}int lcp(int a,int b){    a=Rank[a];    b=Rank[b];    if (a>b) swap(a,b);    return height[askRMQ(a+1,b)];}char str[MAXN];int r[MAXN];int sa[MAXN];int main(){    while (scanf("%s",str) ==1 )    {        int len=strlen(str);        int n=2*len+1;        for (int i=0;i<len;i++) r[i]=str[i];        for (int i=0;i<len;i++)            r[len+1+i] = str[len-1-i];        r[len] = 1;        r[n] = 0;        da(r,sa,Rank,height,n,250);        for (int i=1;i<=n;i++)            RMQ[i]=height[i];        initRMQ(n);        int ans=0,st;        int tmp;        for (int i=0;i<len;i++)        {            tmp=lcp(i,n-i);            if (2*tmp>ans)            {                ans=2*tmp;                st=i-tmp;            }            tmp=lcp(i,n-i-1);            if (2*tmp-1>ans)            {                ans=2*tmp-1;                st=i-tmp+1;            }        }        str[st+ans]=0;        printf("%d\n",ans);    }    return 0;}
0 0