zoukankan      html  css  js  c++  java
  • 【BZOJ-2342】双倍回文 Manacher + 并查集

    2342: [Shoi2011]双倍回文

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1799  Solved: 671
    [Submit][Status][Discuss]

    Description

    Input

    输入分为两行,第一行为一个整数n,表示字符串的长度,第二行有n个连续的小写的英文字符,表示字符串的内容。

    Output

    输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文子串不存在,则输出0

    Sample Input

    16
    ggabaabaabaaball

    Sample Output

    12

    HINT

    N<=500000

    Source

    Solution

    看完题大体的思路就是先一遍Manacher,O(n)求出回文串,然后进行判断

    题目中说的很清楚,双倍回文串长度一定是4的倍数,即为偶数,那么Manacher出来的回文串中心一定在字符间添加的'#'上

    那么考虑要求的东西 y+p[y]>=x && y>=x-p[x]/2,思考一个枚举的方法

    枚举j,如果j不能覆盖到当前的i,那么一定是不符合覆盖到i+1的,所以,之后的所有事和它无关,可以忽略,这样想,维护一下就好了,采取并查集

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define maxn 500010
    char S[maxn],s[maxn<<1];
    int n,len,mx,id,p[maxn<<1],fa[maxn<<1],ans;
    void PreWork()
    {
        memset(p,0,sizeof(p));
        len=n<<1|1;
        for (int i=1; i<=n; i++)
            s[i<<1]=S[i],s[i<<1|1]='#';
        s[0]='$'; s[1]='#'; s[len+1]='%';
    }
    void Manacher()
    {
        PreWork();
        for (int i=1; i<=len; i++)
            {
                if (mx>i) p[i]=min(p[id*2-i],mx-i);
                    else p[i]=1;
                while (s[i-p[i]]==s[i+p[i]]) p[i]++;
                if (p[i]+i>mx) mx=p[i]+i,id=i;
            }
    }
    int find(int x) {if (fa[x]==x) return x; else return fa[x]=find(fa[x]);}
    int main()
    {
        scanf("%d",&n); scanf("%s",S+1);
        Manacher();
        for (int i=1; i<=len; i++)
            if (s[i]=='#') fa[i]=i; else fa[i]=i+1;
        for (int i=3; i<=len-1; i+=2)
            {
                int f=find(max(i-p[i]/2,1));
                while (f<i && f+p[f]<i) fa[f]=find(f+1),f=fa[f];
                if (f<i && (i-f)*2>ans) ans=(i-f)*2; 
            }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    高德地图周边搜索与搜索提示(三)
    jupyter notebook 添加目录
    Ubuntu 下简单完全卸载MySQL 以及便捷安装
    Ubuntu中安装MySQL,更改默认用户密码
    python-pip版本更新
    概率论与数理统计--->陈希孺---书籍链接下载
    机器学习实战-书籍链接下载
    Markdown安装/破解/下载
    Kaggle比赛入门比赛--Titanic-测试玩--
    python机器学习算法简介
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5528671.html
Copyright © 2011-2022 走看看