zoukankan      html  css  js  c++  java
  • manacher模板

    给定一个字符串,要求O(n)时间求出其最长回文串长度。

    首先我们是会O(n^2)的暴力的,就是枚举每个字符作为对称中心,再枚举相同的相邻字符作为对称中心,然后求得答案。

    能不能优化呢?

    我们发现,当一个字符串是回文串时,它满足完全对称,比如:

    abadaba

    设p[i]为以i为中心的回文半径,则p为:

    1 2 1 4 1 2 1

    然后发现右半边竟然可以O(1)出解!

    然后就可以有第一步优化。

    回到上面,按中心分类,回文分为两种。

    能不能将他们都归为满足优化1的那一种?

    答案是能的。在每个字符前后加没有意义的字符,比如 ' # ';

    这就是优化2。

    就有了manacher算法:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    char a[51000050],b[51000050];
    int len;
    int p[102000050];
    void manacher()
    {
        int mx = 0,mid =0;
        for(int i=1;i<=((len<<1)|1);i++)
        {
            if(i<mx)p[i] = min(p[2*mid-i],mx-i+1);
            else p[i]=1;
            while(b[i-p[i]]==b[i+p[i]])p[i]++;
            if(i+p[i]-1>mx)
            {
                mx = i+p[i]-1;
                mid = i;
            }
        }
    }
    int main()
    {
        scanf("%s",a+1);
        len = strlen(a+1);
        b[0]='!',b[(len<<1)+2]='^';
        b[1]='#';
        for(int i=1;i<=len;i++)
        {
            b[i<<1] = a[i];
            b[i<<1|1] = '#';
        }
        manacher();
        int ans = 0;
        for(int i=1;i<=((len<<1)|1);i++)
        {
            ans=max(ans,p[i]);
        }
        printf("%d
    ",ans-1);
        return 0;
    }
  • 相关阅读:
    Rust-数据类型
    Rust-智能指针
    Rust-使用包、Crate和模块管理不断增长的项目
    Rust-Slice类型
    Rust-引用与借用
    Rust 的核心功能-所有权(ownership)
    How to fix “sudo: command not found error”
    ABC195 F
    CF1501D Two chandeliers【拓展欧几里得+二分】
    CCA的小球【容斥定理】
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9671487.html
Copyright © 2011-2022 走看看