题目链接
题意:
求最长回文串
思路:
Manacher求解
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1000000;
string s, s_new;
int p[2 * maxn + 5];
int init(){
int len = s.length();
s_new += '$';
s_new += '#';
for (int i = 0; i < len; ++i) {
s_new += s[i];
s_new += '#';
}
s_new += '\0';
return s_new.length(); //返回 构建新字符串 s_new的长度
}
int Manacher() {
int len = init(); //取得新字符串长度
int mx = 0, id = 1; // mx 标记以id 为中心最长回文串的右端点
int maxlen = 1;
for (int i = 1; i < len; ++i) {
// 之后的两种情况 i 在 mx内
if(i < mx){
if(mx - i > p[2 * id - i]) { // i 关于 id 的对称点是(2 * id - i)
p[i] = p[2 * id - i];
} else {
p[i] = mx - i;
}
} else { // i不在mx 内
p[i] = 1;
}
while(s_new[i - p[i]] == s_new[i + p[i]])// 不需边界判断,因为左有'$',右有'\0'
++p[i];
// 我们每走一步 i,都要和 mx 比较,我们希望 mx 尽可能的远,这样才能更有机会执行 if (i < mx)这句代码,从而提高效率
if (mx < i + p[i]) {
mx = i + p[i];
id = i;
}
maxlen = max(p[i], maxlen); //记录最长串
}
return maxlen - 1;
}
int main(){
getline(cin, s);
printf("%d\n", Manacher());
return 0;
}