zoukankan      html  css  js  c++  java
  • BZOJ 2565 最长双回文串 (Manacher)

    题目大意:一个双回文串被定义为,这个串在某个位置断开,前面一段和后面一段都是回文串,求最长的双回文串

    并没有想出怎么线性求出$R_{i}$数组= =,只想了个线段树,但竟然要区间修改等差数列再维护最大值,我并不会,一看就不是正解

    正解是先用$Manacher$求出以$i$为回文中心,最长的回文半径$p_{i}$

    定义$L_{i}$表示以i结尾最长的回文串,$R_{i}$表示以$i$开头最长的回文串

    在求$p_{i}$的过程中,我们只需要求出回文边界的$L,R$

    $L_{i+p_{i}-1}=max(p_{i}-1)$,$R_{i-p_{i}+1}=max(p_{i}-1)$

    再正向/反向扫一次求出每个位置实际的$L,R$

    $L_{i}=max(L_{i},L{i+2}-2)$,$R_{i}=max(R_{i},R_{i-2}+2)$

    由于使用了$Manacher$算法,故能作为回文边界的只能是$'#'$,所以从头到尾扫$'#'$统计答案即可

     1 #include <cmath>
     2 #include <queue>
     3 #include <vector>
     4 #include <cstdio>
     5 #include <cstring>
     6 #include <algorithm>
     7 #define NN 200100
     8 #define MM 1510
     9 #define ll long long
    10 #define dd double  
    11 #define uint unsigned int
    12 #define mod 1000000007
    13 #define idx(X) (X-'a')
    14 #define eps (1e-9)
    15 using namespace std;
    16  
    17 int n,nn;
    18 char str[NN],a[NN];
    19 int p[NN],L[NN],R[NN];
    20  
    21 int main()
    22 {
    23     scanf("%s",str+1);
    24     n=strlen(str+1);
    25     a[1]='#';
    26     for(int i=1;i<=n;i++)
    27         a[2*i]=str[i],a[2*i+1]='#';
    28     nn=2*n+1;p[1]=1;
    29     int mr=2,mid=1;
    30     for(int i=2;i<=nn;i++){
    31         if(i<mr) p[i]=min(p[2*mid-i],mr-i);
    32         else p[i]=1;
    33         while(a[i-p[i]]==a[i+p[i]]) p[i]++;
    34         if(i+p[i]>mr) 
    35             mr=i+p[i],mid=i;
    36         L[i+p[i]-1]=max(L[i+p[i]-1],p[i]-1);
    37         R[i-p[i]+1]=max(R[i-p[i]+1],p[i]-1);
    38     }
    39     for(int i=1;i<=nn;i+=2)
    40         R[i]=max(R[i],R[i-2]-2);
    41     for(int i=nn;i>=1;i-=2)
    42         L[i]=max(L[i],L[i+2]-2);
    43     int ans=0;
    44     for(int i=1;i<=nn;i+=2)
    45         ans=max(ans,R[i]+L[i]);
    46     printf("%d
    ",ans);    
    47     return 0;
    48 }
  • 相关阅读:
    ubuntu 14.04 (desktop amd 64) 下载
    ubuntu16.04 server(amd 64) 下载
    vim/vi中移动光标键会变成A,B,C,D的解决办法
    ubuntu 14.04(desktop amd 64) nginx 安装启动停止
    ubuntu-server14.04 网络配置
    selenium-chrome-headless
    selenium-firefox-headless
    哈希表-java
    冒泡排序-java
    wc的使用
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10021169.html
Copyright © 2011-2022 走看看