URAL 1297(Palindrome,后缀数组)最长回文串

来源:互联网 发布:网络精灵pipopa 编辑:程序博客网 时间:2024/05/16 11:31

把A反过来接一起,然后后缀数组。

#include<cstdio>#include<cstring>#include<vector>#include<algorithm>#define maxn 5005using namespace std;int r[maxn];int Rank[maxn],sa[maxn],height[maxn];int wa[maxn],wb[maxn],wv[maxn],ws[maxn];char a[maxn],b[maxn];int cmp(int *r,int a,int b,int le){return r[a]==r[b]&&r[a+le]==r[b+le];}void da(int *r,int *sa,int n,int m){int i,j,p,*x=wa,*y=wb,*t;for ( i = 0; i < m; i++) ws[i]=0;for ( i = 0; i < n; i++) ws[ x[i] = r[i] ]++;for ( i = 1; i < m; i++) ws[i]+=ws[i-1];for ( i = n-1; i >= 0; i--) sa[--ws[x[i]]]=i;for ( j = 1,p=1; p <n ; j*=2,m=p){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++) wv[i]=x[y[i]];for ( i = 0; i < m; i++) ws[i]=0;for ( i = 0; i < n; i++) ws[wv[i]]++;for ( i = 1; i < m; i++) ws[i]+=ws[i-1];for ( i = n-1; i >= 0 ; i--) sa[--ws[wv[i]]]=y[i];for (t=x,x=y,y=t,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++;}return ;}void calheight( int *r,int *sa,int n){int i,j,k=0;for ( i = 0; i <=n ; i++) Rank[sa[i]]=i;for(i=0;i<n;height[Rank[i++]]=k)for(k?k--:0,j=sa[Rank[i]-1];r[i+k]==r[j+k];k++);return ;}struct pi{    int min;}pp[100*maxn];void build(int le,int ri,int tot){    if(le==ri)    {        pp[tot].min=height[le];        return ;    }    int mid;    mid=(le+ri)/2;    build(le,mid,2*tot);    build(mid+1,ri,2*tot+1);    pp[tot].min=min(pp[2*tot].min,pp[2*tot+1].min);    return ;}int query(int le,int ri,int tot,int ll,int rr){    int p,q;    p=100000000;    q=100000000;    if(le>ri)        return 0;    if(le<=ll&&ri>=rr)    {        return pp[tot].min;    }    int mid;    mid=(ll+rr)/2;    if(le<=mid)    {        p=query(le,ri,2*tot,ll,mid);    }    if(ri>mid)    {        q=query(le,ri,2*tot+1,mid+1,rr);    }    if(p==100000000&&q==100000000)        return 0;    return min(p,q);}char c[maxn];int main(){    int i,n,m,p,k,f;    while(scanf("%s",a)!=EOF)    {        n=(int)strlen(a);        p=n;        for(i=0;i<n;i++)            r[i]=a[i]-min('A','a')+2;        r[n]=200;        for(i=n+1;i<2*n+1;i++)            r[i]=a[2*n-i]-min('A','a')+2;        r[2*n+1]=0;        n=2*n+1;        da(r,sa,n+1,400);        calheight(r, sa, n);        m=-1;        build(2,n,1);        for(i=0;i<p;i++)        {            for(int j=p+1;j<n;j++)            {                if(Rank[i]<Rank[j])                   k= query(Rank[i]+1,Rank[j],1,2,n);                else                    k= query(Rank[j]+1,Rank[i],1,2,n);                if(k>0&&i+k==p-(j-p-1))                {                    if(k>m)                    {                    for(f=i;f<i+k;f++)                        c[f-i]=a[f];                        m=k;                    }                }            }        }        for(i=0;i<m;i++)            printf("%c",c[i]);        printf("\n");    }    return 0;}


0 0
原创粉丝点击