功能:求最长回文串
1、统计奇偶
方法:在各个字符间插入特殊字符,如’#’。为省略边界判断常在开始再加入’(’。
如:ababac变为)#a#b#a#b#a#c#
这样所有的回文串的长度都变为奇数。而原回文串的长度为现在回文串半径减1。
如: $#a#b#a#b#a#c#
半径长度 11214161412121
回文串长度 00103050301010
如果mx>i,则有以下两种情况
情况一:i+len[j]-1<mx,则len[i]=len[j]
情况二:i+len[j]-1>=mx,则len[i]=mx-i+1,然后依次枚举判断S[mx+1…(增大)]==s[2*i-mx-1...(减小)]
如果mx<=i,则将则len[i]=1,然后依次枚举判断
S[i+1…(增大)]==s[i-1...(减小)]
#include <cstdio>
#include <iostream>
#include <cstring>
#define orz cout << "AK IOI"
using namespace std;
const int N = 1e7 + 1e6 + 5;
char s[N], str[N << 1];
int le, id, mx, len[N << 1], ans = -1;
void getstr()
{
int k = 0;
str[k++] = '$';
for(int i = 0; i < le; i++)
{
str[k++] = '#';
str[k++] = s[i];
}
str[k++] = '#';
le = k;
}
int main()
{
cin >> s;
le = strlen(s);
getstr();
for(int i = 1; i <= le; i++)
{
if(mx > i) len[i] = min(len[2 * id - i], mx - i);//分别为两种情况
else len[i] = 1;//第三种情况
while(str[i + len[i]] == str[i - len[i]])//多余的部分进行比对
len[i]++;
if(len[i] + i > mx)
mx = len[i] + i, id = i;
}
for(int i = 1; i <= le; i++)
ans = max(ans, len[i]);
printf("%d", ans - 1);
return 0;
}