zoukankan      html  css  js  c++  java
  • bzoj 2342 [Shoi2011]双倍回文

    发现每个可行的答案是两个短的回文串拼成的一个长的回文串
    所以短串一定是长串的某个后缀
    建出来回文自动机后,在$fail$树$dfs$即可

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define N 500050
     7 using namespace std;
     8 int nxt[N],len[N],ch[N][26],cnt,last;
     9 char s[N];
    10 void init(){
    11     nxt[0]=nxt[1]=1;
    12     len[1]=-1;cnt=1;
    13 }
    14 int getfail(int x,int en){
    15     while(s[en]!=s[en-len[x]-1])x=nxt[x];
    16     return x;
    17 }
    18 int e=1,head[N];
    19 struct edge{
    20     int v,next;
    21 }ed[N];
    22 void add(int u,int v){
    23     ed[e].v=v;
    24     ed[e].next=head[u];
    25     head[u]=e++;
    26 }
    27 int ans;
    28 int vis[N];
    29 void insert(int t,int en){
    30     int now=getfail(last,en);
    31     if(!ch[now][t]){
    32         int x=++cnt;
    33         len[x]=len[now]+2;
    34         int f=getfail(nxt[now],en);
    35         nxt[x]=ch[f][t];add(nxt[x],x);
    36         ch[now][t]=x;
    37     }
    38     last=ch[now][t];
    39 }
    40 void dfs(int x){
    41     if(len[x]%4==0&&vis[len[x]>>1])ans=max(ans,len[x]);
    42     vis[len[x]]++;
    43     for(int i=head[x];i;i=ed[i].next)
    44         dfs(ed[i].v);
    45     vis[len[x]]--;
    46 }
    47 int n;
    48 int main(){
    49     init();
    50     scanf("%d",&n);
    51     scanf("%s",s);
    52     for(int i=0;i<n;i++)
    53         insert(s[i]-'a',i);
    54     dfs(0);
    55     printf("%d
    ",ans);
    56     return 0;
    57 }
    View Code
  • 相关阅读:
    Switch开关按钮控件----------WinForm控件开发系列
    图片旋转播放控件----------WinForm控件开发系列
    谷歌密码查看器
    Tarjan求LCA
    [题解]Hankson的趣味题
    [NOI Online]文具订购
    二分图判定
    hash表
    KMP算法
    拓扑排序入门
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/8119776.html
Copyright © 2011-2022 走看看