bzoj千题计划305:bzoj2565: 最长双回文串(回文自动机)
https://www.lydsy.com/JudgeOnline/problem.php?id=2565
正着构造回文自动机
倒过来再构造一个回文自动机
分别求出以位置i开始的和结尾的最长回文串
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 100001 char ss[N]; int s[N]; int L1[N],L2[N]; struct TREE { int tot,last; int len[N],tr[N][26],fail[N]; int p,c,np,t; int n; void clear() { tot=1; last=0; memset(tr[0],0,sizeof(tr[0])); memset(tr[1],0,sizeof(tr[1])); fail[0]=1; fail[1]=0; len[0]=0; len[1]=-1; s[0]=-1; n=0; } int newnode(int f) { tot++; memset(tr[tot],0,sizeof(tr[tot])); fail[tot]=0; len[tot]=len[f]+2; return tot; } int extend(int c) { s[++n]=c; p=last; while(s[n-1-len[p]]!=c) p=fail[p]; if(!tr[p][c]) { np=newnode(p); t=fail[p]; while(s[n-1-len[t]]!=c) t=fail[t]; fail[np]=tr[t][c]; tr[p][c]=np; } else np=tr[p][c]; return len[last=np]; } }tree; int main() { scanf("%s",ss+1); int n=strlen(ss+1); tree.clear(); for(int i=1;i<=n;++i) L1[i]=tree.extend(ss[i]-'a'); tree.clear(); for(int i=n;i;--i) L2[i]=tree.extend(ss[i]-'a'); int ans=0; for(int i=1;i<n;++i) ans=max(ans,L1[i]+L2[i+1]); printf("%d",ans); }