这篇文章很好http://blog.sina.com.cn/s/blog_70811e1a01014esn.html
我的代码:
1 #include<cstdlib> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 6 using namespace std; 7 8 char st[100010],s[100010]; 9 int rad[100010]; 10 int mxn = 0,k,ans; 11 12 int main() 13 { 14 scanf("%s",st); 15 int len = strlen(st); 16 for (int i = 0; i < len; ++i) 17 { 18 s[(i<<1)+1] = st[i]; 19 s[(i<<1)+2] = '#'; 20 } 21 len = len << 1; 22 s[0] = '?'; 23 for (int i = 1; i <= len;) 24 { 25 while (s[i-mxn-1] == s[i+mxn+1]) mxn++; 26 rad[i] = mxn; 27 for (k = 1; k <= mxn && rad[i-k]!=rad[i]-k; ++k) 28 rad[i+k] = min(rad[i-k],rad[i]-k); 29 i += k; 30 mxn = max(mxn-k,0); 31 } 32 for (int i = 1; i <= len; ++i) 33 if (i % 2) ans = max(ans,((rad[i]>>1)<<1)+1); 34 else ans = max(ans,((rad[i]+1)>>1)<<1); 35 for (int i = 1; i <= len; ++i) 36 printf("%c ",s[i]); 37 puts(""); 38 for (int i = 1; i <= len; ++i) 39 printf("%d ",rad[i]); 40 puts(""); 41 printf("%d\n",ans); 42 return 0; 43 }
其实很简单,就是将当前的点作为“回文中点”将其后面回文中的字符的作为中点的长度,通过对称求出来,因为前面的回文长度已经全部求出来了。因为每个点的回文长度只求了一次,所以复杂度为O(n)。
浙公网安备 33010602011771号