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;
}
posted @ 2018-02-06 20:01  aziint  阅读(78)  评论(0编辑  收藏  举报
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.