zoukankan      html  css  js  c++  java
  • 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
    ",ans); return;
    59 }
    60 
    61 int main(){
    62     File("PAM");
    63     work();
    64     return 0;
    65 }
  • 相关阅读:
    poj 2728 Desert King(最小比率生成树,迭代法)
    HDU
    hud 2089 不要62 (数位dp)
    食物链(带全并查集)
    docNet基础学完感想
    zoj 1081 (改进的弧长算法)(转)
    zoj 1962 How Many Fibs?(字符串化为数字处理)
    zoj 1109 zoj 1109 Language of FatMouse(字典树)
    iOS开发网络数据之AFNetworking使用
    iOS 使用AFNetworking
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6863346.html
Copyright © 2011-2022 走看看