BZOJ 2342: [Shoi2011]双倍回文 回文自动机
建立一个回文自动机,然后开一个桶遍历一下回文树就好了.
code:
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#define N 500007
using namespace std;
char S[N];
int tot,last,n,ans;
vector<int>G[N];
int ch[N][26],len[N],pre[N],ss[N],bu[N];
int newnode(int x) { return len[++tot]=x,tot; }
void Initialize()
{
pre[0]=1,len[1]=-1,tot=1,ss[0]=-1;
for(int i=1;i<=n;++i) ss[i]=S[i]-'a';
}
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;
}
last=ch[p][c];
}
void setIO(string s) { freopen((s+".in").c_str(),"r",stdin); }
void dfs(int u)
{
bu[len[u]]++;
if((len[u]%4==0)&&bu[len[u]/2]) ans=max(ans,len[u]);
for(int i=0;i<G[u].size();++i) dfs(G[u][i]);
--bu[len[u]];
}
int main()
{
// setIO("input");
int i,j;
scanf("%d%s",&n,S+1);
Initialize();
for(i=1;i<=n;++i) extend(ss[i],i);
for(i=2;i<=tot;++i) G[pre[i]].push_back(i);
dfs(0);
printf("%d\n",ans);
return 0;
}

浙公网安备 33010602011771号