首页 > 其他分享 >高铁拉我,马拉车——记高铁路上的manacher

高铁拉我,马拉车——记高铁路上的manacher

时间:2024-01-22 14:01:38浏览次数:26  
标签:rt manacher 记高 扩展 mid 拉车 复杂度 回文

目录

前言

不得为什么,总会在奇奇怪怪的时候特定时间看算法比平常看得舒服多了,之前看字符串匹配的时候自然是准备把马拉车一起看了的,但是那时候看不下去,昨天回家的高铁上再次看了看,觉得格外的亲切,emmm

问题引入

对于一个字符串,要求求出最长的回文子串,如何操作

思路一览

  • 找出字符串的所有字串,判断是否是回文串,时间复杂度是n2*n=n3
  • 对于每一个字符进行中心扩展,时间复杂度是n2
  • 还有一个是二分加哈希的做法,不过不太了解,私密马赛,时间复杂度是nlogn
  • 最后一个就是本文记录的manacher算法,可以在线性时间内解决该问题,也就是说,时间复杂度达到了n

manacher高效的原因

回文串中的镜像也是回文串,简化了中心扩展的次数

以上图为例,现在要求以点i为中心的最长的回文半径,那么i之前的点最长的回文半径已求出(这句话是不是听起来有一点点的耳熟),我们假设在前面点的记录的最长的回文半径中心是mid,lt和rt分别是它的左右边界,以mid为对称中心,i的对称点为j,我们就可以通过j的状态来推i的状态(这下更熟了吧,这不就是dp嘛,emmm)

具体情况讨论

  • i在rt内
    • jlt > midlt

      根据回文串的对称性,那么i的回文串长度和j的回文串长度一样
    • jlt <= midlt

      这种情况最多只能得出mid回文串内的部分是可以回文的,其余部分就要继续扩展了
  • i在rt外

    此时rt外的部分并没有扩展,因此只能确定i该点是回文的,其余部分需要向外扩展

小问题的讨论

可以看出,manacher算法是对中心扩展的一种改进,但是问题来了,中心扩展好像只对奇回文子串好使,如aba可以从b开始扩展,但是abba是怎么样扩展而来的的呢,因此这个好像就不适用了,我们就要对原先的字符串进行一些改造,比如,在每个字符之间加入一些不可能出现在原字符串的内容,首尾也要加,这样就可以将原先的要讨论的奇偶性全部转化为奇了,例如#a#b#a#和#a#b#b#a#,个人倾向于再在首尾加上不同的特殊符号,防止溢出

code

//p数组用于存放回文串的长度
string change(string s) {
    int lth = s.size();
    string res;
    res += string("$#");
    for(int i=0; i<lth; i++) res += s[i], res += string("#");
    res += string("#");
    return res;
}
void manacher(string s) {
    int n = s.size();
    //mid是当前最长回文串的中心结点,rt则是其右边界
    int mid = 0, rt = 0;
    for(int i=1; i<n; i++) {
        //这里分别是两种情况,一种是可以找到对称点,一种是不可以
        p[i] = (i >= rt) ? 1 : min(p[(mid<<1) - i], rt - i);
        while(s[i+p[i]] == s[i-p[i]]) ++p[i];
        if(i+p[i] > rt) {
            //更新结点操作
            mid = i;
            rt = i + p[i];
        }
    }
}

标签:rt,manacher,记高,扩展,mid,拉车,复杂度,回文
From: https://www.cnblogs.com/notalking569/p/17979904

相关文章

  • 马拉车算法
    马拉车算法chars[maxn],ss[maxn];intp[maxn];intlen,center;intcnt=1;voidinit(){memset(s,0,sizeofs);cnt=1,s[0]='@';intlen=strlen(ss);for(inti=0;i<len;i++){s[cnt++]='#';s[cnt++]=ss......
  • 【CF30E】Tricky and Clever Password 题解(manacher + exKMP)
    manacher+exKMP+二分。感觉是最粗暴的方法,想出来之后自己硬莽了4k,荣获题解区最长。Solution约定:下文所提及到的所有的回文串,均指奇长度回文串。显然把题目拆成两个部分,中间的回文串,以及两边相同的连续子串。考虑一下从哪个入手比较好。忘记是咋想的了,易得从两边相同......
  • Manacher与exKMP(扩展KMP,Z函数)
    Manacher算法该算法由GlennK.Manacher在1975年提出,首先注意到回文串的对称中心特性可能有所不同(中心可能为一个字符或者是在两个字符之间),那么我们将字母之间插入隔板,这两个回文串的对称中心就都在一个字符上了,suchas"|A|B|B|A|"、"|A|B|C|B|A|"过程对于一个回文串,有且......
  • KMP算法和Manacher算法
    KMP算法KMP算法解决的问题KMP算法用来解决字符串匹配问题:找到长串中短串出现的位置.KMP算法思路暴力比较与KMP的区别暴力匹配:对长串的每个位,都从头开始匹配短串的所有位.KMP算法:将短字符串前后相同的部分存储在\(next\)数组里,让之前匹配过的信息指导之后的匹配.......
  • manacher
    \(\mathrm{manacher}\)算法可以在线性时间内求出一个串中的最长回文子串。为了解决偶回文串的中心点非整数,在每个字符之间添加一个字符#。为防止越界问题再在串的前后加上奇怪的符号。记\(mx\)为当前最长回文串的右端,\(id\)为串中心的位置,\(len_{id}\)为以\(id\)为中心......
  • 洛谷P3805 【模板】manacher
    题目链接:https://www.luogu.com.cn/problem/P3805manacher算法模板题。参考资料:https://oi-wiki.org/string/manacher/示例程序:#include<bits/stdc++.h>usingnamespacestd;constintmaxn=2.2e7+5;intn;chars[maxn/2],a[maxn];intp[maxn];voidinit(){......
  • Manacher学习笔记
    1.介绍:manacher算法用于求解回文子串问题,可以求出以一个串中每一点为中心的最长回文半径,相当于可以求出所有回文子串2.引入:假如要求出一个串所有长度为奇数的回文子串,暴力怎么做?枚举以每个点为回文中心,向两侧扩展,分别比较a[p+i]与a[p-i]时间复杂度O(n^2)我们考虑优化,我们......
  • manacher 回文串处理算法
    忘了具体什么时候写的,应该是2023.8初这算是个算法复习,因为我太菜了以前学的都不会了。manacher回文串处理算法其实这个我已经看两天了却一直没有看懂,觉得自己很愚笨,结果发现是自己一直不想去理解吧,然后今天仔细研究了以后发现就是那么个东西,没有什么很深奥的东西,那就自己整......
  • 洛谷:manacher
    【模板】manacher算法题目描述给出一个只由小写英文字符\(\texttta,\textttb,\textttc,\ldots\texttty,\textttz\)组成的字符串\(S\),求\(S\)中最长回文串的长度。字符串长度为\(n\)。输入格式一行小写英文字符\(\texttta,\textttb,\textttc,\cdots,\textt......
  • Manacher——最快的找最长回文算法
    Manacher马拉车——Manacher算法解决的问题给定一串字符串str,求str内的最长回文子串,我们可以从最朴素的算法开始,逐渐深入Manacher算法。朴素穷举法一直枚举字符串str的子串,并判断子串是否为回文。这个时间复杂度直接到\(O(n^3)\)了,一般题目都会超时。中心扩散法作为一个回文......