#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 2e6 + 10;
int n; //提前记录字符串的长度,减少复杂度
char s[maxn]; //输入的字符串
int len[maxn]; //在i出最大的延申半径
int mx = 0;
void init_s() {
//扩展字符串 栗子:abc --> @#a#b#c#$就是在每个字符的左右边都出现#,在边界放两个不同的字符
n = strlen(s);
n = n * 2;
for (int i = n; i >= 2; i -= 2) {
s[i] = s[i / 2 - 1];
s[i - 1] = '#';
}
s[0] = '@', s[n + 1] = '#', s[n + 2] = '$', n += 2;
}
void Manacher() {
init_s(), len[1] = 1; //扩展初始化
int mid = 0, r = 0;
for (int i = 2; i <= n; i++) {
if (r > i) {
len[i] = min(r - i, len[2 * mid - i]);
}
else len[i] = 1;
while (s[i + len[i]] == s[i - len[i]]) ++len[i]; //尝试扩展
if (i + len[i] > r) {
//如果成立,说明扩展到r的右边去了,所以更新r和mid
r = i + len[i];
mid = i;
}
mx = max(mx, len[i] - 1); //更新答案
}
}
int main() {
cin >> s;
Manacher();
cout << mx << endl;
return 0;
}
Template-Manacher
Guess you like
Origin blog.csdn.net/qq_45739057/article/details/105525577
Recommended
Ranking