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 }
  • 相关阅读:
    杂记
    实战:PSP上运行Windows 95
    [英语阅读笔记] CodeSnip: Uploading Multiple Files At Once
    整理网上的一些关于sharepoint编码方面的最佳实践 Virus
    ASP.NET、SharePoint中另存文件的长文件名被截断的原因及解决办法 Virus
    一个由Erlang引发的故事,关于语言和工资的故事 Virus
    ASP.NET统计图表控件 Virus
    关于验证码的思考 Virus
    Design Pattern 设计模式【观察者】 Virus
    moss开发实施过程中遇到的问题总结:项目层面 Virus
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10142573.html
Copyright © 2011-2022 走看看