zoukankan      html  css  js  c++  java
  • BZOJ 2342 [SHOI2011]双倍回文 (回文自动机)

    题目大意:略

    先建出$PAM$

    因为双倍回文串一定是4的倍数,所以找出$PAM$里所有$dep$能整除4的节点

    看这个串是否存在一个回文后缀,长度恰好为它的一半,沿着$pre$链往上跳就行了

    暴跳可能会$T$,所以倍增了跳

    如果被卡空间,可以把trs数组当成倍增数组

     1 #include <cmath>
     2 #include <vector>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <algorithm>
     6 #define N1 500100
     7 #define S1 (N1<<1)
     8 #define ll long long
     9 #define uint unsigned int
    10 #define rint register int 
    11 #define dd double
    12 #define il inline 
    13 #define inf 0x3f3f3f3f
    14 #define idx(X) (X-'a')
    15 using namespace std;
    16 
    17 int gint()
    18 {
    19     int ret=0,fh=1;char c=getchar();
    20     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
    21     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
    22     return ret*fh;
    23 }
    24 int len;
    25 namespace PAM{
    26 int trs[N1][26],pre[N1],dep[N1],la,tot;
    27 void init(){la=tot=1,pre[0]=pre[1]=1,dep[1]=-1;}
    28 int chk(char *str,int i,int p){return str[i-dep[p]-1]!=str[i]?1:0;}
    29 void insert(char *str,int i)
    30 {
    31     int p=la,np,fp,c=idx(str[i]);
    32     while(chk(str,i,p)) p=pre[p];
    33     if(!trs[p][c])
    34     {
    35         np=++tot;
    36         dep[np]=dep[p]+2;
    37         fp=pre[p];
    38         while(chk(str,i,fp)) fp=pre[fp];
    39         pre[np]=trs[fp][c];
    40         trs[p][c]=np;
    41     }
    42     la=trs[p][c];
    43 }
    44 int multi()
    45 {
    46     int ans=0,i,j,x;
    47     trs[1][0]=trs[1][1]=0;
    48     trs[0][0]=trs[0][1]=0;
    49     for(i=2;i<=tot;i++) trs[i][0]=i,trs[i][1]=pre[i];
    50     for(j=2;j<=20;j++)
    51         for(int i=2;i<=tot;i++)
    52         trs[i][j]=trs[ trs[i][j-1] ][j-1];
    53     for(i=2;i<=tot;i++)
    54         if(dep[i]%4==0)
    55         {
    56             x=i;
    57             for(j=20;j>=0;j--)
    58                 if(dep[trs[x][j]]>=dep[i]/2) x=trs[x][j];
    59             if(dep[x]!=dep[i]/2) continue;
    60             ans=max(ans,dep[i]);
    61         }
    62     return ans;
    63 }
    64 };
    65 char str[N1];
    66 
    67 int main()
    68 {
    69     //freopen("t2.in","r",stdin);
    70     //freopen("a.out","w",stdout);
    71     scanf("%d",&len);
    72     scanf("%s",str+1);
    73     PAM::init();
    74     for(int i=1;i<=len;i++) PAM::insert(str,i);
    75     printf("%d
    ",PAM::multi());
    76     return 0;
    77 }
  • 相关阅读:
    练习2-15 求简单交错序列前N项和(15 分)
    js预解析实例
    one:arguments对象伪数组
    第一章 评估工具
    第6章条件处理
    第五章----过程
    第4章 数据传递.寻址和算术运算
    第3章 汇编语言基础
    第2章-------------IA-32处理器体系结构
    第一章-------基本概念
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10142573.html
Copyright © 2011-2022 走看看