首页 > 其他分享 >Manacher

Manacher

时间:2024-12-13 20:45:07浏览次数:2  
标签:相等 int Manacher 复杂度 s1 回文

Manacher,O(n)求字符串最长回文子串的良心算法
首先,求最长回文字串的两个个方法,第一个是将所有字串列出来然后逐个判断,时间复杂度高达O(n3),这里不多赘述,然后就是选择一个字符,向两边扩展,判断是否相等,相等则长度自增。时间复杂度高达O(n2)
然后就是可以用hash来判断回文,时间复杂度为O(nlogn),多数也能过,但是让你写马拉车的题除外——

咳,废话少说,学马拉车之前要明确一个性质
1.如果一个字符串回文,则它有一个回文中心
2.关于回文中心对称的两个回文子串相等
3.则可以得出一个大回文串中某个点的回文半径(即回文串的长度/2上取整)等于和它关于 大回文串回文中心 对称的点的回文半径相等,因为对称的两点再大回文串内的两边都拥有同样的东西
4.所以就可以用之前算过的来更新大回文串右半边的点,,,但是在进行下一步之前,是应该进行依托拓展的,拓展方法参照O(n^2)思路
5.然后就是对于回文串超过了大回文串的右端点的情况,更新大回文串的右端点,然后继续重复上述操作...
再就是一些细节的处理——emm好像manacher这种东西也没有太多的细节。。。
好的,接下来就放一道板子(你知道对于依托没怎么切过蓝题的孩子来说,点开一个算法全是蓝紫的感觉咩)
Manacher纯板子
6.哦对了,发现有一个东西忘讲了,就是奇回文串和偶回文串的判断方式的差别,如果在两个字符中间放一个‘#’,就可以使偶回文串变成奇回文串,比如aa变成#a#a#

接下来就是代码——

点击查看代码
#include<bits/stdc++.h>
using namespace std;
string s1,ss;
const int N=2.4e7+10;
int n,d[N];

namespace Cathy
{
    inline void rebuild()
    {
        int k=0;
        ss+="$#";
        k=1;
        for(int i=1;i<=n;i++)
        {
            ss+=s1[i-1];
            ss+='#';
            k+=2;
        }
        n=k;
    }

    inline void work()
    {
        d[1]=1;
        for(int i=2,l,r=0;i<=n;i++)
        {
            if(i<=r)
            {
                d[i]=min(d[r-i+l],r-i+1);
            }
            while(ss[i-d[i]]==ss[i+d[i]])
            {
                d[i]++;
            }
            if(i+d[i]-1>r)
            {
                r=i+d[i]-1;
                l=i-d[i]+1;
            }
        }
    }

    inline void Main()
    {
        cin>>s1;
        n=s1.size();
        rebuild();
        work();
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            ans=max(ans,d[i]);
        }
        cout<<ans-1<<"\n";
    }

}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    Cathy::Main();
    
    return 0;
}

标签:相等,int,Manacher,复杂度,s1,回文
From: https://www.cnblogs.com/cathyzro/p/18605792

相关文章

  • 【知识】Manacher
    Manacher#include<iostream>#include<cstring>#include<algorithm>usingnamespacestd;constintN=2e7+10;intn;chara[N],b[N];intp[N];voidinit(){intk=0;b[k++]='$',b[k++]='#';......
  • [学习笔记 #8] Manacher 算法
    目录[学习笔记#8]Manacher算法[学习笔记#8]Manacher算法至今都不会exKMP/dk/dk/dk[]里的是我还不确定的。Manacher是对序列上每个点求它作为[回文中心]的最长回文子串长度/端点的算法,时间复杂度是\(O(|S|)\)。具体地,从左往右加入每个点,记录当前字符串的回......
  • Manacher 马拉车
    Manacher马拉车,一种为了求字符串中最长的回文字串的算法。这个算法是从暴力的方法转化过来的,暴力肯定是枚举字符串每个字符作为中心,然后向外扩展,这样的复杂度为\(O(n^2)\)。而Manacher则是按照回文对称的性质的进行优化的,首先回文串有奇数串\(aba\)和偶数串\(abba\)如果......
  • Manacher 算法
    引入:万恶的字符串问题你是否看到字符串就感到迷茫而无所适从?你是否看到“border”“回文”等字眼就感到大脑宕机只会暴力?如果你像我一样有这种症状,不妨一起来学习一下Manacher算法。当你掌握了Manacher之后,你会发现,很多字符串问题都变成了板子,而你再也不用担心因为字符串抱......
  • 算法·理论:Manacher 笔记
    \(\text{Manacher}\)来啦!\(\text{Manacher}\)并没有什么前置知识,比\(\text{KMP}\)简单多了。前置处理\(\text{Manacher}\)算法用于解决回文串相关问题,先看几个基本概念:回文中心、回文半径,这些看字面意思就能猜到。还有一个重要问题:对于回文串,有长度为奇数或长度为偶数之......
  • manacher
    manacher用途:找字符串中的最长的回文子串。考虑该问题【模板】manacher求最长回文串长度。该如何做?暴力\(O(n^2)\)就是枚举回文中心,向外拓展。代码太简单了,就不挂了。其实是懒得打二分+hash\(O(n\logn)\)将字符串正向hash,反向hash,枚举回文中心,二分答案即可......
  • 回文结构 manacher & PAM 马拉车 & 回文树
    manacher马拉车通过在每个字符间插入一个特殊字符,使得字符串长度为奇数,从而保证每个字符都有中心。在每个中心记录回文串的长度。马拉车的扩展方式和\(Z\)函数类似。都是通过映射之前已经算过的位置,然后尽可能的向右扩展。复杂度\(O(n)\)通常马拉车的题目统计回文串需要与其他......
  • P3805 【模板】manacher
    原题链接题解细节所有字符的回文半径初始化为1rmax=1ans=1code#include<bits/stdc++.h>#definelllonglongusingnamespacestd;voidsolve(){strings;cin>>s;strings1;for(inti=0;s[i];i++){s1+='#';s1+=......
  • 题解:CodeForces 835 D Palindromic characteristics[区间dp/马拉车Manacher]
    CodeForces835DD.Palindromiccharacteristicstimelimitpertest:3secondsmemorylimitpertest:256megabytes*inputstandardinputoutputstandardoutputPalindromiccharacteristicsofstring\(s\)withlength\(|s|\)isasequenceof\(|s|\)in......
  • 「字符串」Manacher算法(马拉车)/ LeetCode 05(C++)
    给你一个字符串 s,找到 s 中最长的回文子串。示例1:输入:s="babad"输出:"bab"解释:"aba"同样是符合题意的答案。示例2:输入:s="cbbd"输出:"bb"思路我们回想中心扩散法:某字符处的中心扩散完毕后,其实已经将它身前身后的字符段落都搜索过了,那么如果我们搜索其后的字......