最长回文(Manacher算法 时间复杂度O(n))

来源:互联网 发布:一本书学会做数据分析 编辑:程序博客网 时间:2024/05/21 17:29


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


最长回文

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9288    Accepted Submission(s): 3199


Problem Description
给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等
 

Input
输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
 

Output
每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
 

Sample Input
aaaaabab
 

Sample Output
43
 

Source
2009 Multi-University Training Contest 16 - Host by NIT
 

Recommend
lcy   |   We have carefully selected several similar problems for you:  1358 1686 3336 3065 3067 
 




AC  code:

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>#include<queue>#include<vector>#include<map>#define LL long long#define MAXN 1000010using namespace std;char s1[MAXN],s2[MAXN];int p[MAXN];int len,ans;void pre(){int i,j,k;len=strlen(s1);s2[0]='$';s2[1]='#';for(i=0;i<len;i++){s2[i*2+2]=s1[i];s2[i*2+3]='#';}len=len*2+2;s2[len]=0;}int Manacher(){int i;int mx=0;int id;ans=0;for(i=1;i<len;i++){if(mx>i)p[i]=min(p[2*id-i],mx-i);elsep[i]=1;for(;s2[i+p[i]]==s2[i-p[i]];p[i]++);ans=max(ans,p[i]);if(p[i]+i>mx){mx=p[i]+i;id=i;}}return ans-1;}int main(){while(~scanf("%s",s1)){pre();printf("%d\n",Manacher());}return 0;}


0 0