板子题
每次插入我们可以找到这个点的最长后缀回文,那么这个回文 u u u不仅可以作用于 u u u
还让 f a i l [ u ] , f a i l [ f a i l [ u ] ] , f a i l [ f a i l [ f a i l [ u ] ] ] . . . . . fail[u],fail[fail[u]],fail[fail[fail[u]]]..... fail[u],fail[fail[u]],fail[fail[fail[u]]].....出现次数都加一
暴力跳 f a i l fail fail显然超时,所以我们只把贡献暂时挂在最长后缀这里
因为 f a i l [ u ] fail[u] fail[u]的索引一定小于 u u u
所以我们可以倒序枚举,给前面的加贡献,算当前的答案…
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 5e5+10;
int n;
char a[maxn];
struct PAM
{
int len[maxn],fail[maxn],zi[maxn][26],id,las,cnt[maxn];
PAM()
{
id = las = 1;
fail[0] = 1,fail[1] = 1,len[0] = 0,len[1] = -1;
}
int get_fail(int u,int index)
{
while( a[index]!=a[index-len[u]-1] ) u = fail[u];
return u;
}
void insert(int c,int index)
{
int u = get_fail(las,index);
if( !zi[u][c] )
{
int now = ++id, v = get_fail( fail[u],index );
fail[now] = zi[v][c], len[now] = len[u]+2;
zi[u][c] = now;
}
las = zi[u][c]; cnt[las]++;
}
void build()
{
int n = strlen( a+1 );
for(int i=1;i<=n;i++) insert( a[i]-'a'+1,i );
int ans = 0;
for(int i=id;i>=2;i--)
cnt[fail[i]] += cnt[i];
for(int i=2;i<=id;i++)
ans = max( ans,len[i]*cnt[i] );
cout << ans;
}
}pam;
signed main()
{
cin >> ( a+1 );
pam.build();
}