/**********************
洛谷 P3649
题意:给你一个字符串,求一个最大的值(回文字符串长度*出现次数)
思路:回文树模板题,取一个max(len[i]*cnt[i])从[0-id)(注意ll)
关于回文树模板:id表示每种本质不同的回文字符串编号,len数组表示
每种本质不同的回文字符串长度,cnt数组表示每种不同回文字符串的个数
******************************/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll maxn = 300005;
char str[maxn];
struct PAM
{
ll nxt[maxn][26],fail[maxn],len[maxn],cnt[maxn],S[maxn];
ll id,last,n;
ll newnode(ll x)
{
for(ll i=0;i<26;i++) nxt[id][i]=0;
cnt[id]=0;
len[id]=x;
return id++;
}
void init()
{
id=0;
newnode(0);
newnode(-1);
fail[0]=1;
S[0]=-1;
last=n=0;
}
ll getfail(ll x)
{
while(S[n-len[x]-1]!=S[n]) x=fail[x];
return x;
}
void Insert(ll c)
{
c-='a';
S[++n]=c;
ll cur=getfail(last);
if(!nxt[cur][c]){
ll now=newnode(len[cur]+2);
fail[now]=nxt[getfail(fail[cur])][c];
nxt[cur][c]=now;
}
last=nxt[cur][c];
cnt[last]++;
}
void getsum()
{
for(ll i=id-1;i>=0;i--){
cnt[fail[i]]+=cnt[i];
}
}
}pam;
int main()
{
scanf("%s",str);
pam.init();
ll len=strlen(str);
for(ll i=0;i<len;i++){
pam.Insert(str[i]);
}
pam.getsum();
ll ans = 0;
for(ll i=0;i<pam.id;i++){
ans=max(ans,(pam.cnt[i]*pam.len[i]));
}
printf("%lld\n",ans);
return 0;
}
回文树的题目:HDU 6599