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