模版:
#include<stdio.h> #include<string.h> #include<algorithm> #include<map> using namespace std; const int maxn = 2e5 + 10; char s[maxn], sNew[maxn<<1]; int p[maxn<<1], id, mx=0; int L, R; //回文串在原串的左右端点位置 int Init() { int len = strlen(s); sNew[0] = '$'; sNew[1] = '#'; int j = 2; for (int i = 0; i < len; i++){ sNew[j++] = s[i]; sNew[j++] = '#'; } sNew[j] = '\0'; return j; } int Manacher() { int len = Init(); int max_len = -1; mx = 0; for (int i = 1; i < len; i++){ if (i < mx) p[i] = min(p[2 * id - i], mx - i); else p[i] = 1; ///在对象不是字符串时候,原本为了防止越界是左有'$' ///右有'\0',现在右边就没有'\0',需要人为填充替代! while (sNew[i - p[i]] == sNew[i + p[i]]) p[i]++; if (mx < i + p[i]){ id = i; mx = i + p[i]; } //max_len = max(max_len, p[i] - 1); //// 如果题目不要求输出回文串在原串的位置,则用下面代码更新答案 if(max_len < p[i]){ ///这里L、R记录的是最长回文子串在原串的左右端点 max_len = p[i]; L = (i - p[i])>>1; R = (i + p[i] - 4)>>1; ///R = (i + p[i])/2 -2; } } return max_len; /// 最后如若需要找到的回文串则是 /// for(int i=(id-mx+1);i<=(id+mx-1);i++) /// if(sNew[i]!='#'&&sNew[i]!='$') ///注意你设置的开头符号和填充符号,不同则需要修改 /// putchar(sNew[i]); }