思路:套用迴文串的模板求出最長迴文串之後, 用兩個數組L與R分別存 最長迴文串右邊界在當前節點的最長迴文串長度,以及左邊界在當前節點的最長迴文串長度。然後分別在掃描一下兩個數組,得到迴文串左右邊界在當前節點的最長迴文串長度。然後取最大值就好了。
#include <iostream>
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int Max_N = 500000+100;
int Ma[Max_N * 2];
int Mp[Max_N * 2];
void Manacher(char s[], int len)
{
int l = 0;
Ma[l++] = 1010;
Ma[l++] = 1000;
for (int i = 0; i < len; i++) {
Ma[l++] = int(s[i]);
Ma[l++] = 1000;
}
Ma[l] = 0;
int mx = 0, id = 0;
for (int i = 0; i < l; i++) {
Mp[i] = mx > i? min(Mp[2*id-i], mx-i):1;
while (Ma[i+Mp[i]] == Ma[i-Mp[i]]) Mp[i]++;
if (i + Mp[i] > mx) {
mx = i + Mp[i];
id = i;
}
}
}
char buf[Max_N];
int l[Max_N];
int r[Max_N];
int n;
int main()
{
while (scanf("%s", buf) != EOF) {
Manacher(buf, strlen(buf));
memset(l, 0, sizeof(l));
memset(r, 0, sizeof(r));
int len = strlen(buf);
int max1 = 0;
for (int i = 0; i < 2*len+2; i++) {
int s = Mp[i] - 1 + i;
int s2 = i - Mp[i] + 1;
l[s] = max(l[s], Mp[i] - 1);
r[s2] = max(r[s2], Mp[i] - 1);
}
int ss1 = 0;
for (int i = 2*len + 1; i >= 0; i--) {
if (ss1 != 0) {
ss1--;
l[i] = max(l[i], ss1);
ss1 = l[i];
}
else ss1 = l[i];
}
ss1 = 0;
for (int i = 0; i < len * 2 + 2; i++) {
if (ss1 != 0) {
ss1--;
r[i] = max(r[i], ss1);
ss1 = r[i];
}
else ss1 = r[i];
}
for (int i = 0; i < 2*len + 2; i++) {
max1 = max(max1, l[i] + r[i]);
}
printf("%d\n", max1);
}
return 0;
}