思路:馬拉車裸題,我們用一個p[i]數組代表以i爲中心的最大回文半徑。這裏用了一個小技巧,如果一個串是aaaa這樣的,那我們插入不相干的字符使它成爲#a#a#a#a#,這樣無論這個串是奇數還是偶數都會變成奇數,容易處理。馬拉車的效率在於,在暴力處理前面的迴文時,我們可以初始化後面的p[j],減少暴力的時間,這樣複雜度就從O(n^2)變成了O(n)。這裏要注意一下,我們得到的p[i]所指向的不一定是數字,也有可能是‘#’,比如$#a#b#b#a#中最大的是p[5]。
代碼:
#include<set>
#include<iostream>
#include<algorithm>
const int maxn = 110000+5;
const int INF = 0x3f3f3f3f;
using namespace std;
int p[maxn<<1];
char snew[maxn<<1],s[maxn];
int init(){
int len = strlen(s),cnt = 0;
snew[0] = '$';
for(int i = 0;i < len;i++){
snew[++cnt] = '#';
snew[++cnt] = s[i];
}
snew[++cnt] = '#';
snew[++cnt] = '\0';
return cnt;
}
int Manacher(){
int cnt = init();
int id = 0,ans = -1;
for(int i = 2;i < cnt;i++){
if(p[id] + id > i){
p[i] = min(p[2*id - i],p[id] + id - i);
}
else p[i] = 1;
while(snew[i - p[i]] == snew[i + p[i]])
p[i]++;
if(id + p[id] < i + p[i])
id = i;
ans = max(ans,p[i] - 1);
}
return ans;
}
int main(){
while(scanf("%s",s) != EOF){
printf("%d\n",Manacher());
}
return 0;
}