Template-Manacher

#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;
}

Guess you like

Origin blog.csdn.net/qq_45739057/article/details/105525577