【后缀数组】 求字符串的最长回文串

来源:互联网 发布:淘宝客鹊桥计划怎么建 编辑:程序博客网 时间:2024/04/28 03:04


求一个串的最长回文子串

把原串的反串加个原串后面,中间加个没有出现过的字符

然后,原串中,下标i在反串中对应的位置为2*l-i

如果求以i为对称轴的回文串,我们求suffix(i)和suffix(2*l-i)的LCP

如果求以i和i+1为对称轴的回文串,我们求suffix(i+1)和suffix(2*l-i)的LCP


代码:

#include <iostream>#include <cstdio>using namespace std;const int maxn=2010;char s[maxn];int sa[maxn],t[maxn],t2[maxn],c[maxn];int n;void build_sa(int n, int m){    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;        //直接利用sa数组排序第二关键字        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=0;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;    }}//LCPint ranks[maxn],height[maxn],d[maxn][15];void getHeight(){    int i,j,k=0;    for(i=0;i<=n;i++) ranks[sa[i]]=i;    for(i=0;i<n;i++)     {        if(k) k--;        int j=sa[ranks[i]-1];        while(s[i+k]==s[j+k]) k++;        height[ranks[i]]=k;    }}void RMQ(){for(int i=1;i<n;i++) d[i][0]=height[i];for(int j=1;(1<<j)<n;j++)for(int i=1;i+(1<<j)-1<n;i++)d[i][j]=min(d[i][j-1],d[i+(1<<(j-1))][j-1]);}int LCP(int L,int R){int a=ranks[L],b=ranks[R];if(a>b)swap(a,b);a++;    int t=(int)(log(double(b-a+1))/log(2.00));    return min(d[a][t],d[b-(1<<t)+1][t]);}void solve(){int res=0,id=0;int l=n/2;for(int i=0;i<l;i++){int t=LCP(i,n-i-1);if(2*t-1>res){res=2*t-1;id=i;}if(s[i]==s[i+1]){t=LCP(i+1,n-i-1);if(2*t>res){res=2*t;id=i;}}}cout<<res<<endl;id=id-(res-1)/2;for(int j=0;j<res;j++){cout<<s[id+j];}cout<<endl;}int main(){cin>>s;n=strlen(s);s[n]=24;for(int i=0;i<n;i++){s[n+i+1]=s[n-i-1];}n=2*n+1;s[n+1]='\0';build_sa(n+1,200);getHeight();RMQ();solve();return 0;}

0 0
原创粉丝点击