Description
考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最
大出现值。 \(n\leqslant 10^5\)
Solution
回文自动机.
回文自动机的构造很简单..直接暴力找到第一个,然后暴力找到fail...
由于一个长度为n的字符串中本质不同的回文串个数是\(O(n)\)的,所以每个结点只会被fail访问一次,所以复杂度还是\(O(n)\)的..
https://pan.baidu.com/s/1o6BtDJs
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 3e5+500;
const int M = 27;
struct PAM {
int cnt,lst;
int go[N][M],l[N],f[N],sz[N];
char s[N];
void init() { scanf("%s",s+1),l[1]=-1,f[0]=1,cnt=1; }
void Add(int x,int n) {
int p=lst;
while(s[n-l[p]-1]!=s[n]) p=f[p];
if(!go[p][x]) {
int np=++cnt,k=f[p];l[np]=l[p]+2;
while(s[n]!=s[n-l[k]-1]) k=f[k];
f[np]=go[k][x],go[p][x]=np;
}sz[lst=go[p][x]]++;
}
LL get_ans() {
int n=strlen(s+1);
for(int i=1;i<=n;i++) Add(s[i]-'a'+1,i);
LL res=0;
for(int i=cnt;~i;--i) sz[f[i]]+=sz[i],res=max(res,(LL)l[i]*sz[i]);
return res;
}
}py;
int main() {
py.init();
printf("%lld\n",py.get_ans());
return 0;
}