O(n)算法。求p[id]时,mx是递增的,故算法是严格线性的。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define N 1000005
#define mod 20140518
#define inf 1 << 29;
typedef long long LL;
int n, m;
char a[N];
char b[N << 1];
int p[N << 1];
void change(){
b[0] = '$';
int len = strlen(a);
for(int i = 0; i <= len; i++){
b[i * 2 + 1] = '#';
b[i * 2 + 2] = a[i];
}
}
void pk(){
int mx = 0;
int id;
int len = strlen(b);
for(int i = 1; i < len; i++){
if(mx > i)
p[i] = min(p[2 * id - i], mx - i);
else p[i] = 1;
for(;b[i + p[i]] == b[i - p[i]]; p[i]++);
if(p[i] + i > mx){
mx = p[i] + i;
id = i;
}
}
}
int main(){
int n;
scanf("%d", &n);
while(n--){
scanf("%s", a);
memset(p, 0, sizeof(p));
change();
pk();
int len = strlen(b);
int ans = 0;
for(int i = 1; i < len; i++){
if(p[i] - 1 > ans)ans = p[i] - 1;
}
printf("%d\n", ans);
}
return 0;
}