写在前面

manachermanachermanacher比想象中好理解得多

至少它给了我学习字符串的信心

能干啥

manachermanachermanacher,中文马拉车(您别说,这名字还挺形象),主要用于计算字符串每一个位置为对称中心的回文串长度(等价于个数)

包括偶回文,即长度为偶数的回文串

算法流程

考虑下面的问题:给一个字符串,求最长回文子串

我会暴力!

枚举判断O(n3)O(n^3)O(n3)

我会优化!

考虑到以ccc为中心,acbacbacb不是回文串,左右怎么接都不是回文串

所以可以枚举中间点(偶回文判断一下即可),然后向两边拓展

复杂度O(n2)O(n^2)O(n2)

我会玄学!

O(n2)O(n^2)O(n2)还不够 不符合字符串算法均为线性复杂度公理

在此基础上继续优化

我们记录maxrmaxrmaxr为目前找到的回文串右端点的最右的位置 pospospos为这个回文串的对称中心

开一个数组pip_ipi​表示回文半径(和其他文章不同,本文回文半径指一个端点到中心的距离,即直接相减)

回文串最本质的特征是什么?左右关于中心对称。

如果一个回文串对称中心的一侧有另一个回文子串,那么对称过去也有一个相同长度的回文子串


黄色部分完全一致,这就是manacher的核心

(先不考虑偶回文)

① i&lt;maxri&lt;maxri<maxr(取不取等于无所谓)

设j,ij,ij,i关于pospospos对称 即j=pos∗2−ij=pos*2-ij=pos∗2−i

根据上面的推导,令pi=pjp_i=p_jpi​=pj​即可

当然如果jjj为中心的最长回文左端点越界了

那就不能保证上面的性质(实际上可以保证不成立),所以要和j−maxlj-maxlj−maxl(即maxr−imaxr-imaxr−i)取minminmin。

jjj越界时还需要让iii继续拓展。当然为了刷短代码减少讨论,都拓展一下好了

②i≥maxri \geq maxri≥maxr


啥都不能保证,直接暴力扩展

综上:

  1. 如果i&lt;maxri&lt;maxri<maxr,按上述条件更新pip_ipi​
  2. 暴力拓展
  3. 更新maxrmaxrmaxr和pospospos

然后……对,没了,就三行。

这就是manachermanachermanacher的全过程,复杂度O(n)O(n)O(n),后面有证明

实现

上面没有讨论偶回文,主要是转化过程比较难看,容易使人丧失信心。

其实也不难。只需要在字符两两之间加一个字符,如‘#’;然后首尾也加上‘#’,再在开头加一个标识符防止越界。注意要和之前的不同,如‘@’

这样偶回文可以看做中心是‘#’的回文

普及T1模拟水平

这样处理后,所有回文串左右端点都是‘#’,然后就可以跑了

证明

什么?不是只改了一个地方吗?怎么变O(n)O(n)O(n)了?

回顾整个流程,真正暴力拓展的时候要么jjj左端点越界,要么iii越界(jjj左端点没越界时,根据反证法,iii实际上无法拓展)

jjj左端点越界时,iii右端点出生点就在maxrmaxrmaxr,再拓展就超出去了

也就是说,每次暴力拓展,都意味着maxrmaxrmaxr更新,而maxrmaxrmaxr只会往右跑

换一个角度,实际上暴力拓展是把maxrmaxrmaxr推到最右边,次数是O(n)O(n)O(n)的

所以总复杂度是O(n)O(n)O(n)的

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#define MAXN 1000005
using namespace std;
char s[MAXN],ss[MAXN];
int pos,maxr;
int p[MAXN];
int main()
{scanf("%s",s+1);int n=strlen(s+1);for (int i=1;i<=n;i++) ss[i<<1]=s[i],ss[(i<<1)|1]='#';n=(n<<1)|1,ss[0]='@',ss[1]='#';strcpy(s,ss);for (int i=1;i<=n;i++){if (i<maxr) p[i]=min(p[(pos<<1)-i],maxr-i);while (s[i-p[i]-1]==s[i+p[i]+1]) ++p[i];if (i+p[i]>maxr) maxr=i+p[i],pos=i;}return 0;
}

由于所有位置为中心的最长回文串左右端点都是‘#’

回文串长度leni=2pi+1−12=pilen_i= \frac {2p_i+1-1}{2} = p_ileni​=22pi​+1−1​=pi​

然后用来搞事情就可以了

Manacher入门相关推荐

  1. 怎么判断一个字符串的最长回文子串是否在头尾_回文自动机入门

    缘起 回文自动机(Palindrome auto machine PAM,有些地方称之为回文树)是回文问题的大杀器~  本文使用一道很简单的题目入门这个精巧的数据结构. hdu 2163 Palind ...

  2. 创新实践部第一次培训---算法入门

    文章目录 引言--我们为什么要学算法 常见基础错误 手(shou)误(jian) 浮点数判等 声明变量和使用变量太远 忘记初始化 数组开小了 变量开小了 建议的代码书写方式 ACM输入输出 ACM错误 ...

  3. dropwizard 连接mysql_Dropwizard入门及开发步骤

    Dropwizard介绍 Dropwizard是一个微服务框架, 是各项技术的一个集成封装.它包含了以下组件: - 嵌入式Jetty,一个应用程序被打包成一个Jar文件,并开始自已嵌入的Jetty容器 ...

  4. 用Construct 2制作入门小游戏~

    今天在软导课上了解到了Construct 2这个神器,本零基础菜鸟决定尝试做一个简单的小游戏(实际上是入门的教程啊= = 首先呢,肯定是到官网下载软件啊,点击我下载~ 等安装完毕后我便按照新手教程开始 ...

  5. Docker入门六部曲——Swarm

    原文链接:http://www.dubby.cn/detail.html?id=8738 准备工作 安装Docker(版本最低1.13). 安装好Docker Compose,上一篇文章介绍过的. 安 ...

  6. Docker入门六部曲——Stack

    原文链接:http://www.dubby.cn/detail.html?id=8739 准备知识 安装Docker(版本最低1.13). 阅读完Docker入门六部曲--Swarm,并且完成其中介绍 ...

  7. Docker入门六部曲——服务

    原文链接:http://www.dubby.cn/detail.html?id=8735 准备 已经安装好Docker 1.13或者以上的版本. 安装好Docker Compose.如果你是用的是Do ...

  8. 【springboot】入门

    简介: springBoot是spring团队为了整合spring全家桶中的系列框架做研究出来的一个轻量级框架.随着spring4.0推出而推出,springBoot可以説是J2SEE的一站式解决方案 ...

  9. SpringBoot (一) :入门篇 Hello World

    什么是SpringBoot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不 ...

最新文章

  1. 科学处理java.lang.StackOverflowError: null异常
  2. 安卓dtmf识别_基于Python的DTMF信号识别
  3. 利用css3实现jQuery中的slideDown和slideUp效果
  4. OAM Kubernetes 标准实现与核心依赖库发布 | 云原生生态周报 Vol. 52
  5. Struts2里的Action返回Json数据
  6. 看漫画,学Linux内核!看完明白小企鹅们在干啥了吧?
  7. UVA 11825 状态压缩DP+子集思想
  8. PAT A 1118. Birds in Forest (25)【并查集】
  9. Java数据解析之XML(原创)
  10. BZOJ 1688: [Usaco2005 Open]Disease Manangement 疾病管理
  11. QueryWrapper、LambdaQueryWrapper以及LambdaQueryChainWrapper用法
  12. 【计算机网络学习笔记04】网络体系架构与网络协议
  13. 腾讯云:开发者实验室
  14. dw里PHP编写格式,Dreamweaver中如何使用模板(附代码)
  15. Android vitamo 实现横竖屏的切换和页面内部的网络视频
  16. Eclipse java.lang.NoClassDefFoundError: org/dom4j/io/SAXReade 错误解决方法
  17. springboot学校快递站点管理系统的设计与实现毕业设计源码111544
  18. Docker:第一章:Docker常用命令
  19. outlook邮箱链接如何用ie打开_Outlook手机邮箱配置文档
  20. XDC IO --- Output Delay Constraints(Vivado)

热门文章

  1. 岛国小姐姐来例假时,男朋友背着她偷偷查手机......
  2. 为什么大部分男生比女生高?原因让你意想不到
  3. 数学特级教师:数学除了做题目,我还必须让他们看这些!
  4. html盒模型向上浮动,HTML5盒模型、浮动和定位
  5. mvn 打包可执行包_用Maven打包发布可执行的jar包
  6. java跨库调用存储_存储库仅在第二个调用数据时发送回ViewModel
  7. http referer 验证防御方法_渗透测试 跨站攻击防御与安全检测手法剖析
  8. Linux语言写的高通滤波,高通滤波器c语言实现
  9. 数据结构——图-最短路径长度中最大的一个
  10. java class类型参数_使用Class对象实例化Java类型参数/ generic