以HYSBZ 3676 回文串 为例
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 3e5+5;
const int sgsz = 26;
//回文树
struct Pam
{
int nxt[maxn][sgsz], S[maxn];
int fail[maxn], num[maxn], cnt[maxn], len[maxn];
int last, n, p;
int Newnode(int l)
{
memset(nxt[p], 0, sizeof(nxt[p]));
cnt[p] = num[p] = 0;
len[p] = l;
return p++;
}
void Init()
{
p = 0;
Newnode(0);
Newnode(-1);
last = 0;
n = 0;
S[n] = -1;
fail[0] = 1;
}
int Get_fail(int x)
{
while(S[n - len[x] - 1] != S[n])
x = fail[x];
return x;
}
void Add(int c)
{
c -= 'a';
S[++n] = c;
int cur = Get_fail(last);
if(!nxt[cur][c])
{
int now = Newnode(len[cur] + 2);
fail[now] = nxt[Get_fail(fail[cur])][c];
nxt[cur][c] = now;
num[now] = num[fail[now]] + 1;
}
last = nxt[cur][c];
cnt[last]++;
}
void Count()
{
for(int i = p - 1; i >= 0; --i)
cnt[fail[i]] += cnt[i];
}
LL Ans()
{
LL ans = 0;
Count();
for(int i = 0; i < p; i++)
ans = max(ans, (LL)len[i] * (LL)cnt[i]);
return ans;
}
}pam;
int main()
{
char s[maxn];
scanf("%s", s);
pam.Init();
int l = strlen(s);
for(int i = 0; i < l; ++i)
pam.Add(s[i]);
printf("%lld\n", pam.Ans());
return 0;
}