这是 liangbob 用来存放一些自己写的傻逼|

园龄:粉丝:关注:

Manacher 算法学习笔记

Manacher 马拉车算法

一、概述与定义

  • 马拉车算法是一种用来解决最长回文串等关于回文串长度问题的算法。

  • 定义一个长度为奇数 x 回文串 s 的回文中心为 x+12

  • 在此定义下,一个有回文中心的回文串必然是一个奇数。

  • 定义一个长度为 n 的回文串 s 的回文长度为 x2

二、做法

  • 以字符串 s=dcbababcd 为例

  • 我们首先在字符串 s 的字符之间插入一个特殊字符 #,变成:

    s=#d#c#b#a#b#a#b#c#d#

  • 这么做的目的就是消除奇数长度字符串和偶数长度字符串的长度差别。可以观察到,一个以 # 为中心的回文串去掉 # 后就是一个偶数长度字符串,一个以字母为中心的字符串就是一个奇数长度字符串。不妨定义 pi 为以 i 为回文中心的最长回文串的回文长度,那么 pi1 就是一个回文串的长度(具体是哪个回文串写出来会比较抽象,这里简略)。

  • 我们再在首尾两端插入一个特殊字符串,以防止遍历的时候越界。定义刚刚没有插的时候的那一段字符串为有效段。

  • 不妨假设 1i1 这一段中,末尾位置最后的回文串的末尾位置为 mx,它是一个以 c 为中心的回文串,

  • 对于 i>mx 的情况,由于前面关于字符串的信息最多到 mx,那么你木得任何办法,只能设置 pi=1,然后首尾扩展。

  • 对于 imx 的情况,不妨假设 i 关于 c 的对称点为 j=2ci,注意到,一个以 i 为回文中心的回文串经过 c 对称后必然也会存在一个以其对称点 j 为回文中心的回文串,原因就是以 i 为回文中心的回文串对称后反了过来,变成了倒序,但依然是一个回文串。

  • 显然,如果 pj 超过了 mxi,说明以 j 为中心的字符串长度超过了 c 的“对称管辖范围”,是否对称还说不定。那么我们的信息最多也就到 mxi 这里,剩下的只能靠暴力拓展了。而如果没超过,那半点问题都没有。

  • 所以我们实现时可以这样

    • 如果 i>mx,那么 pi=1,否则 pi=max(p2ci,mxi)
    • 暴力拓展:当 sipi=si+pi 时,pi 加上 1
    • 更新 mx,如果 i+pi 大于 mx,那么 mx=i+pic=i​。

本文作者:邻补角の杂货铺

本文链接:https://www.cnblogs.com/sslbj/p/18743522

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   邻补角-SSA  阅读(3)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开