后缀数组_最长回文

给定一个字符串,求最长回文子串。
算法分析:
穷举每一位,然后计算以这个字符为中心的最长回文子串。注意这里要分两
种情况,一是回文子串的长度为奇数,二是长度为偶数。两种情况都可以转化为
求一个后缀和一个反过来写的后缀的最长公共前缀。具体的做法是:将整个字符
串反过来写在原字符串后面,中间用一个特殊的字符隔开。这样就把问题变为了
求这个新的字符串的某两个后缀的最长公共前缀
这个做法的时间复杂度为 O(nlogn)

题目:scut oj 2505

#include
#include
#include
#define maxn 400010
using namespace std;
char cpy[200010];
char s[maxn];
int sa[maxn],t[maxn],t2[maxn],c[maxn],Rank[maxn],height[maxn],n;
void build_sa(int m){
    int i,*x=t,*y=t2,*T,p ;
    n++;
    for(i=0;i=0;--i)sa[--c[x[i]]]=i;
    for(int k=1;k<=n;k<<=1)
    {
          p=0;
       for(i=n-1;i>=n-k;--i)y[p++]=i;
       for(i=0;i=k)y[p++]=sa[i]-k;
       for(i=0;i=0;--i)sa[--c[x[y[i]]]]=y[i];
       swap(x,y);
       x[sa[0]]=0;p=1;
       for(i=1;i=n)break;
       m=p;
    }
    n--;
   // for(int i=1;i<=n;++i)printf("%d ",sa[i]+1);
    //printf("\n");

}
void cal_height(){
    int i,j,k=0;
    for(i=1;i<=n;i++)Rank[sa[i]]=i;
    for(int i=0;isum?height[i]:sum;
    }
    return sum;

}
int main(){
    while(scanf("%s",cpy)!=EOF)
    {
        n=strlen(cpy);
        strcpy(s,cpy);
        s[n]='$';
        for(int i=n-1,j=n+1;i>=0;i--,j++)
        {
            s[j]=cpy[i];
        }
        n=2*n+1;
        build_sa(255);
        cal_height();
        printf("%d\n",solve());
    }
}

你可能感兴趣的:(后缀数组_最长回文)