HDU - 4513
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4513
我写过一篇将我对Manacher算法理解的blog:https://blog.csdn.net/weixin_43191865/article/details/90451240
这一题只需要在判断回文串的时候加上一句:ma[i - mp[i]] <= ma[i - mp[i] + 2]
即可
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 7;
int s[maxn], ma[maxn*2],n;
int mp[maxn*2];
void Manacher() {
int l = 0;
ma[l++] = -1;
ma[l++] = -2;
for (int i = 0; i < n; i++) {
ma[l++] = s[i];
ma[l++] = -2;
}
ma[l] = 0;
int maxx = 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]] && ma[i - mp[i]] <= ma[i - mp[i] + 2]) {
mp[i]++;
}
if (i + mp[i] > mx) {
mx = i + mp[i];
id = i;
}
maxx = maxx > mp[i] ? maxx : mp[i];
}
printf("%d\n", maxx - 1);
}
int main() {
int T;
cin >> T;
while (T--) {
cin >> n;
for (int i = 0; i < n; i++) scanf("%d", s + i);
Manacher();
}
return 0;
}
HDU - 3294
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3294
解法:只需要在马拉车的基础上加入max_id , maxx 记录 mp[max_id]的最大值。
这个时候输出的那两个下标就等于:
(max_id-(maxx-2)-1)/2 (max_id+(maxx-2)-1)/2
化简即可
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 2e5 + 7;
char s[maxn], ma[maxn * 2];
int mp[maxn * 2];
void Manacher(int flag) {
int l = 0;
ma[l++] = '$';
ma[l++] = '#';
int end = strlen(s);
for (int i = 0; i < end; i++) {
ma[l++] = s[i];
ma[l++] = '#';
}
ma[l] = 0;
int maxx = 0, max_id = 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;
}
if (maxx < mp[i]) {
maxx = mp[i];
max_id = i;
}
}
int j;
if (maxx == 2) {
printf("No solution!\n");
}
else {
printf("%d %d\n", (max_id - maxx + 1) / 2 , (max_id + maxx - 3 ) / 2 );
for (int j = max_id - mp[max_id] + 2; j <= max_id + mp[max_id]-2; j+=2) {
printf("%c", ma[j]-flag>='a'?(char)(ma[j]-flag):(char)(ma[j]+26-flag));
}
printf("\n");
}
}
int main() {
char ss[10];
int flag;
while (scanf("%s", ss)!=EOF) {
flag = ss[0] - 'a';
scanf("%s", s);
Manacher(flag);
}
return 0;
}