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 }
  • 相关阅读:
    jquery实现选项卡(两句即可实现)
    常用特效积累
    jquery学习笔记
    idong常用js总结
    织梦添加幻灯片的方法
    LeetCode "Copy List with Random Pointer"
    LeetCode "Remove Nth Node From End of List"
    LeetCode "Sqrt(x)"
    LeetCode "Construct Binary Tree from Inorder and Postorder Traversal"
    LeetCode "Construct Binary Tree from Preorder and Inorder Traversal"
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10142573.html
Copyright © 2011-2022 走看看