bzoj2342 [Shoi2011]双倍回文

Posted wfj_2048

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj2342 [Shoi2011]双倍回文相关的知识,希望对你有一定的参考价值。

Description

技术分享

Input

输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容。

Output

输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文子串不存在,则输出0。

Sample Input

16
ggabaabaabaaball

Sample Output

12

HINT

N<=500000

 

正解:回文自动机。

一道回文自动机的板子题。。我们直接构造字符串的$PAM$,然后在$fail$树上$dfs$,找到一个长度既是$4$的倍数,祖先中又有长度等于它的一半的字符串就行了。

 

 1 //It is made by wfj_2048~
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <complex>
 5 #include <cstring>
 6 #include <cstdlib>
 7 #include <cstdio>
 8 #include <vector>
 9 #include <cmath>
10 #include <queue>
11 #include <stack>
12 #include <map>
13 #include <set>
14 #define inf (1<<30)
15 #define N (500010)
16 #define il inline
17 #define RG register
18 #define ll long long
19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
20 
21 using namespace std;
22 
23 struct edge{ int nt,to; }g[2*N];
24 
25 int ch[N][26],fa[N],l[N],head[N],cnt[N],n,la,sz,num,ans;
26 char s[N];
27 
28 il int gi(){
29     RG int x=0,q=1; RG char ch=getchar();
30     while ((ch<0 || ch>9) && ch!=-) ch=getchar();
31     if (ch==-) q=-1,ch=getchar();
32     while (ch>=0 && ch<=9) x=x*10+ch-48,ch=getchar();
33     return q*x;
34 }
35 
36 il void insert(RG int from,RG int to){
37     g[++num]=(edge){head[from],to},head[from]=num; return;
38 }
39 
40 il void add(RG int c,RG int n){
41     RG int x=la; while (s[n-l[x]-1]!=s[n]) x=fa[x];
42     if (!ch[x][c]){
43     RG int v=++sz,k=fa[x]; l[v]=l[x]+2;
44     while (s[n-l[k]-1]!=s[n]) k=fa[k];
45     fa[v]=ch[k][c],ch[x][c]=v,insert(fa[v],v);
46     }
47     la=ch[x][c]; return;
48 }
49 
50 il void dfs(RG int x){
51     if (l[x]%4==0 && cnt[l[x]/2]) ans=max(ans,l[x]); ++cnt[l[x]];
52     for (RG int i=head[x];i;i=g[i].nt) dfs(g[i].to); --cnt[l[x]]; return;
53 }
54 
55 il void work(){
56     n=gi(),scanf("%s",s+1),l[++sz]=-1,fa[0]=1;
57     for (RG int i=1;i<=n;++i) add(s[i]-97,i);
58     dfs(0),printf("%d\n",ans); return;
59 }
60 
61 int main(){
62     File("PAM");
63     work();
64     return 0;
65 }

 

以上是关于bzoj2342 [Shoi2011]双倍回文的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ2342][Shoi2011]双倍回文

bzoj2342 [Shoi2011]双倍回文 (manacher)

bzoj2342 [Shoi2011]双倍回文

bzoj 2342: [Shoi2011]双倍回文

[BZOJ2342][SHOI2011]双倍回文

BZOJ 2342: [Shoi2011]双倍回文