Manacher,也叫马拉车。是用来查找一个字符串的最长回文子串的线性算法。

一个字符串的长度有可能是偶数也可能是奇数。为了实现方便,对原串略加改动。如 ababca$#a#b#a#b#c#a#,令新串为 sss。

定义 pip_ipi​ 为以 iii 为对称中心的最长回文半径。刚刚栗子的 ppp 为

$ # a # b # a # b # c # a #
1 1 2 1 4 1 4 1 2 1 2 1 2 1

可以发现:

  1. sis_isi​ 在原串的位置为 ⌊i2⌋\lfloor\frac{i}{2}\rfloor⌊2i​⌋。

  2. 非字母字符对应的 pip_ipi​ 为奇数,字母字符对应的 pip_ipi​ 为偶数。在新串中,因为有其它的字符,所以以 iii 为中心的最长回文子串半径为 ⌊pi2⌋\lfloor\frac{p_i}{2}\rfloor⌊2pi​​⌋,以 iii 为中心的最长回文子串长度为 pi−1p_{i} - 1pi​−1。那么初始化是简单明了的。

void init(){str[1] = '$'; str[2] = '#';for (int i = 1; i <= n; i++) str[i * 2 + 1] = s[i], str[i * 2 + 2] = '#';n = (n + 1) * 2 + 1;
}

难点在构造 ppp,从左到右构造 ppp 数组。令 mxmxmx 为以 ididid 为中心的最长回文子串的右边界,有 id+pid=mxid + p_{id} = mxid+pid​=mx。对于当前的 iii,如果有 i<mxi < mxi<mx,那么 pi=min⁡{p2×id−i,mx−i}p_i = \min \{ p_{2 \times id - i}, mx - i\}pi​=min{p2×id−i​,mx−i}。

略证:令 jjj 为 2×id−i2 \times id - i2×id−i,那么 pi=min⁡{pj,mx−i}p_i = \min \{ p_j, mx-i \}pi​=min{pj​,mx−i}。有 i+j2=id\frac{i + j}{2} = id2i+j​=id,故根据中点公式知 ididid 为 iii 与 jjj 的中点。

如下图,对于取 pjp_jpj​ 的情况为 iii 与 jjj 那一段相等。那么 iii 的那一段能更长吗?不能的,因为如果更长,意味着 sl−1=sr+1s_{l-1} = s_{r+1}sl−1​=sr+1​ 了。如果成立,有 l−1l-1l−1 与 匹配 l−1l-1l−1 的点相同,进而有蓝线的成立关系,蓝线成立则与 pjp_jpj​ 已经求出矛盾。

刚才讨论的情况是 pjp_jpj​ 在 ididid 的覆盖范围的,若超出,那么不满足限定 iii 与 jjj 那一段相等。如下图,根据 ididid 是 iii 与 jjj 的中点,可知 pip_ipi​ 最短也是 mx−imx-imx−i,那么可能更大即为 iii 扩展到 mxmxmx 往右呢?不能的,因为若想让蓝线成立,那么有绿线成立,进而有橙线成立,而橙线成立超出了以 ididid 为对称中心 的 mxmxmx 的边界而矛盾。

综上所述。 pi=min⁡{p2×id−i,mx−i}p_i = \min \{ p_{2 \times id - i}, mx - i\}pi​=min{p2×id−i​,mx−i},并随时更新 ididid 与 mxmxmx。

void manacher(){int mx = 0, id = 0;for (int i = 2; i <= n; i++){if (i < mx) p[i] = min(p[id * 2 - i], mx - i);else p[i] = 1;for (; str[i + p[i]] == str[i - p[i]]; p[i]++) if (p[i] + i > mx) id = i, mx = p[i] + i;}
}

马拉车还可用于 hash,所以不一定是字母回文,还可能是数字回文。

#include <bits/stdc++.h>
using namespace std;
#define re register
#define F first
#define S second
typedef long long ll;
typedef pair<int, int> P;
const int N = 3e7 + 1e6 + 5;
const int INF = 0x3f3f3f3f;
int read() {int x = 0, f = 0; char ch = 0;while (!isdigit(ch)) f |= ch == '-', ch = getchar();while (isdigit(ch)) x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();return f ? -x : x;
}
int n, p[N];
char s[N], str[(N << 1) + 100];
void init(){str[0] = '$'; str[1] = '#';for (int i = 0; i < n; i++) str[(i << 1) + 2] = s[i], str[(i << 1) + 3] = '#';n = (n << 1) + 2;
}
void manacher(){int mx = 0, id = 0;for (int i = 1; i < n; i++){if (i < mx) p[i] = min(p[(id << 1) - i], mx - i);else p[i] = 1;for (; str[i + p[i]] == str[i - p[i]]; p[i]++) if (p[i] + i > mx) id = i, mx = p[i] + i;}
}
int main(){scanf("%s", s); n = strlen(s);init(); manacher();int ans = 0;for (int i = 0; i < n; i++) ans = max(ans, p[i]);printf("%d\n", ans - 1);return 0;
}

马拉车 Manacher相关推荐

  1. 傻子都能看懂的马拉车Manacher

    Manacher's Algorithm 马拉车算法操作及原理 package advanced_001;public class Code_Manacher {public static char[ ...

  2. 马拉车Manacher

    马拉车算法我觉得还挺好理解的,只是不知道为什么我看其他博主对与len[i]所求的认为是以这个为中心的最远回文的字母到中心轴的距离.但最后却返回的是最大的len[i]-1. 我对其进行了一些细微的修改, ...

  3. C++马拉车(Manacher)算法

    文章目录 功能 马拉车算法 初始化 主体 时间复杂度 代码 功能 马拉车算法(Manacher's Algorithm):用O(n)O(n)O(n)的时间得到一个字符串中,以每个字符为中心的最长回文的 ...

  4. [LeetCode][M0005]最长回文子串(Java)(马拉车(Manacher)算法)

    题目描述: 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab" 注 ...

  5. 马拉车(manacher),KMP

    manacher: class Solution:'''这里面是利用manacher进一步做从后面添加最少的字串使其成为回文串,leetcode214T是在前面'''def longestPalind ...

  6. 马拉车(manacher)算法——最长回文(hdu3068)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3068 题目描述: Problem Description 给出一个只由小写英文字符a,b,c...y ...

  7. leetcode214. 最短回文串

    214. 最短回文串 难度困难114 给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串.找到并返回可以用这种方式转换的最短回文串. 示例 1: 输入: "aacecaaa& ...

  8. LeetCode-数据结构

    文章目录 应做未做 未弄懂 经典题+易错题 一.长见识的方法 二.杂七杂八积累 三.面试常考题目索引 java刷题常用 树 数组 摩尔投票算法 堆 数据流的中位数 排序 四.基础知识总结 4.x 数组 ...

  9. 2019爪哇部落第十届新生选拔赛 题解

    博采众长,共同进步 A.空军十一号 阅读题 筛选信息 送气球 B.小爪的子阵和 贪心 最大连续字段和的二维升级版 C.爪爪逃逸 模拟+思维 D.小爪的三视图 模拟 立方体 暴力+思维 E.爪哇的路 最 ...

最新文章

  1. Java项目:宠物商城系统(java+Springboot+Maven+mybatis+Vue+mysql)
  2. 高并发下的秒杀系统架构设计实战!
  3. “人在旅途”之随想以及旅游指南(travel.msra.cn)简介
  4. LR+Jenkins实践思路
  5. 基于oracle 的PL/SQL编程 -变量使用
  6. DL之Panoptic Segmentation:Panoptic Segmentation(全景分割)的简介(论文介绍)、全景分割挑战简介、案例应用等配图集合之详细攻略
  7. Ant build.xml程序简单说明
  8. node:http协议、sql、接口
  9. java 大特性_java三大特性
  10. [渝粤教育] 中国地质大学 数据结构 复习题 (2)
  11. plupload使用例子
  12. Java高级架构师需要掌握什么?
  13. python第三方库——requests
  14. JDK各个版本的新特性jdk1.5-jdk8
  15. [教程]智慧KTV小企鹅日志查看
  16. VGG-16网络结构解析
  17. C语言总谐波失真(THD)实现,从理论到应用分析改进详解
  18. php支付宝接口开发提现,ThinkPHP3.2集成 “单笔提现到支付宝账号接口”
  19. 揭秘支付宝中的深度学习引擎:xNN
  20. 服务器网卡芯片b,英特尔Intel 82599ES芯片万兆网卡E10G42BTDA 通过高可靠数据中心网络改造赢得信...

热门文章

  1. 银联支付-手机网页支付接口开发
  2. 第八届蓝桥杯省赛JavaC组真题——详细答案对照(完整版)
  3. SQL部门工资前三高的所有员工
  4. 物流快递系统前、后端+Java语言+SpringBoot项目+MVC三层架构+maven+Mysql+Tomcat+可以用于学习SpringBoot项目入门
  5. Onvif —— onvif 详细介绍
  6. GIPHY软件实现快速制作gif动图
  7. 关于【科技中的设计师】,这可能是最走心的一篇文章
  8. 环保设备“云上查” 排污监管“线上盯”,EasyNVR助力智慧环保
  9. 全国有哪些高等院校开设大数据相关专业?
  10. 关于google Calendar Instance 的删除问题