BZOJ 3676: [Apio2014]回文串 回文自动机
主要是初始化那里需要注意一下.
然后不要忘记每次给 $last$ 节点的大小++
#include <cstdio> #include <string> #include <cstring> #include <algorithm> #define N 300008 #define ll long long using namespace std; char str[N]; namespace PAM { int tot,last; int pre[N],ch[N][26],len[N],ss[N],sz[N]; void init() { ss[0]=-1,pre[0]=1,len[1]=-1,tot=1; for(int i=1,j=strlen(str+1);i<=j;++i) ss[i]=str[i]-'a'; } int newnode(int x) { return len[++tot]=x,tot; } int getfail(int p,int i) { while(ss[i-len[p]-1]!=ss[i]) p=pre[p]; return p; } void extend(int c,int i) { int p=getfail(last,i); if(!ch[p][c]) { int q=newnode(len[p]+2); pre[q]=ch[getfail(pre[p],i)][c],ch[p][c]=q; } ++sz[last=ch[p][c]]; } ll calc() { ll ans=0ll; for(int i=tot;i>=1;--i) ans=max(ans,(ll)sz[i]*len[i]),sz[pre[i]]+=sz[i]; return ans; } }; void setIO(string s) { freopen((s+".in").c_str(),"r",stdin); } int main() { // setIO("input"); int i,j,n; scanf("%s",str+1),n=strlen(str+1); PAM::init(); for(i=1;i<=n;++i) PAM::extend(str[i]-'a',i); printf("%lld\n",PAM::calc()); return 0; }