manacher分析

1.前言

最开始我看blog,化简式子时化简错了,理解了好久

2.算法分析

attention:

1.dp[i]表示以i为中心的回文串的长度的一半

m a n a c h e r manacher manacher 算法非常类似于暴力,只是比暴力多了一个初始化,剪掉了一下情况

暴力做法

枚举中心点,不断向外拓展,直至左右两端点不相同

首先,我们的初始化分为两种情况

(1).dp[index * 2 - i] > max - i

如图,因为 [ i n d e x − d p [ i n d e x ] , i n d e x + d p [ i n d e x ] ] [index - dp[index], index + dp[index]] [indexdp[index],index+dp[index]] (即为用黑色标出的区间)​为一个回文串,所以我们能知道, d p [ i ] dp[i] dp[i] (用绿色标出的区间表示) 的最小值为 m a x − i max- i maxi(用蓝色标出的区间表示)​所以我们的 d p [ i ] dp[i] dp[i] 可以初始化成 m a x − i max - i maxi

(2).dp[index * 2 - i] <= max - i

如图,同理, d p [ i ] dp[i] dp[i] (用绿色标出的区间表示) 的最小值为 d p [ i ∗ 2 − i n d e x ] dp[i * 2 - index] dp[i2index](用红色标出的区间表示)所以我们的 d p [ i ] dp[i] dp[i] 可以初始化成 d p [ i ∗ 2 − i n d e x ] dp[i * 2 - index] dp[i2index]

由于会出现区间大小为偶数的情况,这个时候 T a Ta Ta 的重心点为空,所以我们在每两个字符中间加一个字符(例如 @),在 s [ 0 ] s[0] s[0] 处加一个不同于 刚才加的那个字符 (例如 #)(reason: 为了防止左右扩展时下表为负, e g . eg. eg. a),这样,就不用写两种情况了

真的完了?是的,就这

3.参考代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN = 22 * 1e6 + 5;

int dp[MAXN];
char s[MAXN], tem[MAXN];

int Min (int x, int y) { return x < y ? x : y; }
int Max (int x, int y) { return x > y ? x : y; }

int Init (char *str) {
	int len = strlen (str + 1), cnt = 0;
	tem[0] = '#';
	for (int i = 1; i <= len; i++) {
		tem[++cnt] = '@';
		tem[++cnt] = str[i];
	}
	tem[++cnt] = '@';
	memcpy (str, tem, sizeof tem);
	return cnt;
}

int Manacher (char *str) {
	int index = 0, max = 0, len = strlen (str + 1), res = 0;
	for (int i = 1; i <= len; i++) {
		if (max >= i)
			dp[i] = Min (max - i, dp[(index << 1) - i]);
		else 
			dp[i] = 0;
		while (str[i - dp[i] - 1] == str[i + dp[i] + 1]) dp[i]++;
		if (i + dp[i] > max) {
			max = i + dp[i];
			index = i;
		}
		res = Max (dp[i], res);
	}
	return res;
}

int main () {
	int step = 0;
	while (scanf ("%s", s + 1)) {
		int len = strlen (s + 1);
		if (s[1] == 'E' && s[2] == 'N' && s[3] == 'D' && len == 3) break;
		Init (s);
		printf ("Case %d: %d\n", ++step, Manacher (s));
	}
	return 0;
}
posted @ 2020-11-13 20:27  C2022lihan  阅读(38)  评论(0编辑  收藏  举报