P3805 [Template] manacher algorithm

topic description

Given a string S consisting only of lowercase English characters a,b,c,...y,z, find the length of the longest palindrome in S.

The string length is n.

input format

A string SS composed of a line of lowercase English characters a, b, c, ⋯, y, z.

output format

An integer representing the answer.

Input and output samples

Type #1 to copy

aaa

output #1 copy

3

Instructions/Tips

1≤n≤1.1×107

Ideas:

Brute-force search for palindromic strings:

Spread one character as the center to both sides.

The manacher algorithm is an optimization for palindrome strings:

The first thing to consider is the size of the string, which may be even or odd.

We can subtract them all into odd numbers, just add characters.

Pay attention to the beginning and the end, one is the role of sentry.

The P array represents the length of the small palindrome string whose radius is the center.

#define _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
using namespace std;
const int N = 11000002;
int n, P[N << 1];
char a[N], S[N << 1];
void change() {
	n = strlen(a);
	int k = 0;
	S[k++] = '$';
	S[k++] = '#';
	for (int i = 0; i < n; i++) {
		S[k++] = a[i];
		S[k++] = '#';
	}
	S[k++] = '&';
	n = k;
}
void manacher() {
	int R = 0, C;
	for (int i = 1; i < n; i++) {
		if (i < R) P[i] = min(P[(C << 1)-i] , P[C] + C - i);
		else P[i] = 1;
		while (S[i + P[i]] == S[i - P[i]]) P[i]++;
		if (P[i] + i > R) {
			R = P[i] + i;
			C = i;
		}
	}
}
int main() {
	scanf("%s", a);
	change();
	manacher();
	int ans = 1;
	for (int i = 0; i < n; i++) ans = max(ans, P[i]);
	cout <<  ans - 1;
	return 0;

}

Guess you like

Origin blog.csdn.net/zhi6fui/article/details/128735247