bzoj3676 [Apio2014]回文串

Description

考虑一个只包含小写拉丁字母的字符串 (s)

我们定义 (s) 的一个子串 (t) 的“出现值”为 (t)(s) 中的出现次数乘以 (t) 的长度。

请你求出 (s) 的所有回文子串中的最大出现值。

Input

输入只有一行,为一个只包含小写字母的非空字符串 (s)

Output

一行一个整数,代表所有回文字串的最大出现值。

Sample Input

Case1:abacaba
Case2:www

Sample Output

Case1:7
Case2:4

Solution

转一篇回文树的优质博客
传送门

于是此题是裸题

#include<bits/stdc++.h>
using namespace std;

#define N 300001

long long ans;
int n;
char s[N];
struct pamType {
	int cnt, last;
	int a[N][26], fa[N], len[N], size[N];
	pamType() { cnt = 1; fa[0] = fa[1] = 1; len[1] = -1; }
	void insert(int c, int n) {
		int p = last;
		while (s[n - len[p] - 1] != s[n]) p = fa[p];
		if (!a[p][c]) {
			int now = ++cnt, k = fa[p];
			len[now] = len[p] + 2;
			while (s[n - len[k] - 1] != s[n]) k = fa[k];
			fa[now] = a[k][c]; a[p][c] = now;
		}
		size[last = a[p][c]]++;
	}
	void solve() { for (int i = cnt; i; i--) size[fa[i]] += size[i], ans = max(ans, (ll)size[i] * len[i]); }
}pam;

int main() {
	scanf("%s", s + 1), n = strlen(s + 1);
	for (int i = 1; i <= n; i++) pam.insert(s[i] - 'a', i);
	pam.solve(); cout << ans;
	return 0;
}
原文地址:https://www.cnblogs.com/aziint/p/8423973.html