• [SHOI2011]双倍回文 manacher


    题面:

      洛谷:[SHOI2011]双倍回文‘

    题解:

      首先有一个性质,本质不同的回文串最多O(n)个。

      所以我们可以对于每个i,求出以这个i为结尾的最长回文串,然后以此作为长串,并判断把这个长串从中间劈开后左边的一半是否也是一个回文串(判断左边那半的中点的回文半径是否可以跨过当前长串的中点)。

      复杂度O(n)

     1 // luogu-judger-enable-o2
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 #define R register int
     5 #define AC 1001000
     6 
     7 int n, pos, maxn, ans;
     8 int r[AC];
     9 char a[AC], s[AC];
    10 
    11 void pre(){
    12     scanf("%d%s", &n, a + 1);
    13     s[0] = '$', s[1] = '#';
    14     for(R i = 1; i <= n; i ++) s[2 * i] = a[i], s[2 * i + 1] = '#';
    15 }
    16 
    17 inline void upmax(int &a, int b){
    18     if(b > a) a = b;
    19 }
    20 
    21 void manacher()
    22 {
    23     int b = 2 * n;
    24     for(R i = 1; i <= b; i ++)
    25     {
    26         r[i] = (maxn > i) ? min(r[2 * pos - i], maxn - i + 1) : 1;//这里要取min
    27         while(s[i - r[i]] == s[i + r[i]]) ++ r[i];
    28         
    29         int last = i - r[i] + 1, Next = i + r[i] - 1;
    30         if(s[last] == '#') ++ last, -- Next;
    31         if(i + r[i] - 1 > maxn && last <= i)//last才是整个串的开头
    32         {
    33             for(R j = maxn + 1; j <= Next; j ++)
    34             {
    35                 int l = 2 * i - j;//获取串头
    36                 int sum = (j - l + 1 + 1) >> 1;
    37                 if(s[j] == '#' || sum % 4) continue;//中间是获取实际字符数
    38                 int tmp = (l + j) >> 1, k = (tmp + l) >> 1;                
    39                 if(k + r[k] - 1 >= tmp) upmax(ans, sum); 
    40             }
    41         }
    42         
    43         if(i + r[i] - 1 > maxn) pos = i, maxn = i + r[i] - 1;
    44     }
    45     printf("%d
    ", ans);
    46 }
    47 
    48 int main()
    49 {
    50     //freopen("in.in", "r", stdin);
    51     pre();
    52     manacher();
    53     //fclose(stdin);
    54     return 0;
    55 }
    View Code
  • 相关阅读:
    vue-cli(vue脚手架)简单流程
    windows环境之node.js安装与环境配置
    fiddler的下载和简单使用
    Linux 配置nginx 代理tomcat,配置ssl
    来聊一聊导出数据问题
    作为一个开发人员应该具备怎么样技术栈和职业素养
    NODEJS的误打误撞
    聊一下程序员的日常
    openstack安装部署私有云详细图文
    openstack:OpenStack架构详解,
  • 原文地址:https://www.cnblogs.com/ww3113306/p/10066792.html
Copyright © 2020-2023  润新知