Manacher算法

来源:互联网 发布:淘宝申诉提供虚假凭证 编辑:程序博客网 时间:2024/04/29 13:41

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3068

 

题意:给定一个长度不超过110000的字符串T,求它的最长回文子串。

 

求最长回文子串可以用后缀数组,扩展KMP算法,Manacher算法,其中Manacher算法无论时间还是编程复杂度都是最好的,

其时间复杂度为O(n)

#include <iostream>#include <string.h>#include <stdio.h>using namespace std;const int N=200005<<1;char T[N];   //原字符串char S[N];   //转换后的字符串int  R[N];   //回文半径void Init(char *T){    S[0]='$';    int len=strlen(T);    for(int i=0; i<=len; i++)    {        S[2*i+1]='#';        S[2*i+2]=T[i];    }}void Manacher(char *S){    int k=0,mx=0;    int len=strlen(S);    for(int i=0; i<len; i++)    {        if(mx>i)            R[i]=R[2*k-i]<mx-i? R[2*k-i] : mx-i;        else            R[i]=1;        while(S[i+R[i]]==S[i-R[i]])            R[i]++;        if(R[i]+i>mx)        {            mx=R[i]+i;            k=i;        }    }}int main(){    while(~scanf("%s", T))    {        Init(T);        Manacher(S);        int len=strlen(S);        int ans=1;        for(int i=0; i<len; i++)            ans=R[i]>ans? R[i] : ans;        printf("%d\n", ans-1);    }    return 0;}

 

另外,HDU3294也是一个很好的回文子串题目。

最长回文子串对应原串T中的位置:l = (i - R[i])/2; r = (i + R[i])/2 - 2;