BZOJ 3676: [Apio2014]回文串
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; }