建立回文树得出所有本质不同的回文串,用hash判断每个长度为偶数的回文串其双倍是否是原串的子串
#include<cstdio> #include<algorithm> typedef unsigned long long u64; const int N=500005,P=293; u64 pp[N]={1},h[N],hs[N]; int nx[N][26],fa[N],l[N],t[N],d[N],q[N],ql=0,qr=0,ptr=2,pv=2,len; char s[N]; void ins(int w){ int p=pv,x,c=s[w]-'a'; while(1){ x=w-1-l[p]; if(x>=0&&s[w]==s[x])break; p=fa[p]; } if(nx[p][c]){ pv=nx[p][c]; return; } pv=++ptr; l[pv]=l[p]+2; nx[p][c]=pv; if(!(l[pv]&1))h[pv]=h[p]*P+s[w]+s[w]*pp[l[pv]-1]; if(l[pv]==1){ fa[pv]=2; return; } while(1){ p=fa[p]; x=w-1-l[p]; if(x>=0&&s[w]==s[x]){ fa[pv]=nx[p][c]; break; } } } int main(){ l[1]=-1; fa[1]=fa[2]=1; scanf("%d%s",&len,s); for(int i=1;i<=len;i++)pp[i]=pp[i-1]*P; for(int i=0;i<len;i++)ins(i); for(int i=3;i<=ptr;i++)hs[i]=h[i]; std::sort(hs+3,hs+ptr+1); int ans=0; for(int i=3;i<=ptr;i++){ if(l[i]&1)continue; if(l[i]<ans)continue; u64 v=h[i]*pp[l[i]]+h[i]; if(*std::lower_bound(hs+3,hs+ptr+1,v)==v)ans=l[i]; } printf("%d",ans*2); return 0; }