hdu 3068(最长回文子串O(n))

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

感觉这篇博客写的不错:

http://www.felix021.com/blog/read.php?2040

我就直接上代码了。。。

View Code
 1 #include<iostream>
 2 #include<cstring>
 3 const int N=110010;
 4 using namespace std;
 5 int len;
 6 int p[N<<1];
 7 char s[N],str[N<<1];
 8 //数组p[i]来记录以字符str[i]为中心的最长回文子串向左(或向右)(包括str[i])的长度
 9 //id表示最大回文子串中心的位置
10 //mx则为id+p[id],也就是最大回文子串的边界
11 
12 //最长回文子串O(n)求法
13 void Manacher(){
14     int id,mx=0;
15     for(int i=1;i<len;i++){
16         if(mx>i){
17             p[i]=min(p[(id<<1)-i],mx-i);
18         }else
19             p[i]=1;
20         for(;str[i+p[i]]==str[i-p[i]];p[i]++);
21         if(p[i]+i>mx){
22             mx=p[i]+i;
23             id=i;
24         }
25     }
26 }
27 
28 int main(){
29     while(~scanf("%s",s)){
30         len=strlen(s);
31         str[0]='$';
32         str[1]='#';
33         for(int i=0;i<len;i++){
34             str[(i<<1)+2]=s[i];
35             str[(i<<1)+3]='#';
36         }
37         len=(len<<1)+2;
38         str[len]='\0';
39         Manacher();
40         int ans=-1;
41         for(int i=0;i<len;i++){
42             ans=max(ans,p[i]);
43         }
44         printf("%d\n",ans-1);
45     }
46     return 0;
47 }
原文地址:https://www.cnblogs.com/wally/p/2999097.html