Manacher学习笔记
Manacher算法 可在 \(O(n)\)的时间内求出一个字符串以每个位置为中心的最长回文子串。
原理:根据之前预处理出的回文串长度求得新的回文串长度
我们可以通过在字符中加上'#'来避免长度为偶数回文串没有中心的问题
原串 = "abcd"; 变为
新串 = "#a#b#c#d#";
原串中长度为奇数和偶数的回文串的长度均变为奇数,且原串中回文串的长度为新串回文串半径减一。
设置两个状态 $\max $ 和 \(p\) , \(p\) 表示当前已找到的回文串中,向右延伸最远的中心位置,$\max $ 表示其右端点。
设 \(r(i)\) 表示(新串中)第 \(i\) 个位置的回文半径(回文串长度的一半,包括第 \(i\) 个字符)按从左到右的顺序求解,枚举到第 \(i\) 个字符时,分三种情况考虑:
设\(\ j\) 为\(\ i\) 关于 \(p\) 的对称点,即 \(j = 2p - i\)
\(\max < i\),即向右延伸最远的回文子串(黑色)没有覆盖 \(i\),此时只有 \(r(i) \geq 1\)。
\(\max \geq i\) 且 \(\max - i \geq r(j)\),即向右延伸最远的回文子串(黑色)覆盖了 \(i\),并且以 jj 为中心的最长回文子串完全与以 \(i\) 为中心的最长回文子串对称(蓝色),此时一定有 \(r(i) = r(j)\),即 \(r(i) \geq r(j)\)。
\(\max \geq i\) 且 \(\max - i \geq r(j)\),即向右延伸最远的回文子串(黑色)覆盖了 \(i\),但没有覆盖以 jj 为中心的最长回文子串的对称位置串,所以 \(r(i)\) 只能取被覆盖的(黄色)一部分,即 \(r(i) \geq \max - i\)。
code(伪)
int len;
void prepare(){
len = 0;
s2[++len] = '%';
for(int i = 0; i < s.size(); i++){
s2[++len] = '#';
s2[++len] = s[i];
}
s2[++len] = '#';
}
void manacher(){
int mid = 0, rb = 0;
//此处的rb是 真实值加一
//回文串为(lb, rb) (lb, mid] = [mid, rb) 所以计算半径直接rb - mid;
//因为每次扩展x相当于扩展rb, rb最多扩展n次, 所以O(N);
for(int i = 1; i <= len; i++) {
int x;
if(rb < i) x = 1;
else x = min(p[2*mid - i], rb - i);
while(s2[i+x] == s2[i-x]) x++;
if(i > rb) mid = i, rb = i+x;
p[i] = x;
}
}
ans = max(p[]) - 1;
//原串回文串长度等于新串回文半径减一.
Manacher学习笔记的更多相关文章
- Manacher 学习笔记
\(\\\) \(Manacher\) 一种常用的字符串算法,用于处理一些回文字符相关的问题. 回文串:从前向后和从后向前输出一致. 回文中心:以这里开始,每次向外左右各扩展一个字符得到的回文串的中心 ...
- Manacher算法学习笔记 | LeetCode#5
Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...
- 学习笔记 - Manacher算法
Manacher算法 - 学习笔记 是从最近Codeforces的一场比赛了解到这个算法的~ 非常新奇,毕竟是第一次听说 \(O(n)\) 的回文串算法 我在 vjudge 上开了一个[练习],有兴趣 ...
- 【学习笔记】字符串—马拉车(Manacher)
[学习笔记]字符串-马拉车(Manacher) 一:[前言] 马拉车用于求解连续回文子串问题,效率极高. 其核心思想与 \(kmp\) 类似:继承. --引自 \(yyx\) 学姐 二:[算法原理] ...
- OI知识点|NOIP考点|省选考点|教程与学习笔记合集
点亮技能树行动-- 本篇blog按照分类将网上写的OI知识点归纳了一下,然后会附上蒟蒻我的学习笔记或者是我认为写的不错的专题博客qwqwqwq(好吧,其实已经咕咕咕了...) 基础算法 贪心 枚举 分 ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
- 2014年暑假c#学习笔记目录
2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...
随机推荐
- 《剑指offer》旋转数组中的最小数字
本题来自<剑指offer> 旋转数组中的最小数字 题目: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例 ...
- Client-Side Attacks
1.之前看到中间人攻击方式,要使用ssl服务构架一个劫持会话,使得攻击者和被攻击者客户端连接.ssl 服务(secure Socket Layer安全套接) ,以及后续出现的TSL(Transport ...
- 基于kali linux无线网络渗透测试
1.无线网络渗透测试目前主要有三种方式,分别是暴力破解PIN码,跑握手包,搭建伪热点三种方式,当然还存在其他的方式. 1.1暴力破解 路由器的PIN码由八位0-9的数字组成,PIN码由散步风组成,前四 ...
- 古代猪文:数论大集合:欧拉定理,exgcd,china,逆元,Lucas定理应用
/* 古代猪文:Lucas定理+中国剩余定理 999911658=2*3*4679*35617 Lucas定理:(m,n)=(sp,tp)(r,q) %p 中国剩余定理:x=sum{si*Mi*ti} ...
- python http请求类
# -*- coding: UTF-8 -*- # coding="utf-8" import httplib2 import json from urllib.parse imp ...
- 对象存储服务(Object Storage Service,简称 OSS)
阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量.安全.低成本.高可靠的云存储服务.它具有与平台无关的RESTful API接口,能够提供99.99 ...
- VS2017+mysql5.7 连接数据库生成实体
参考:https://www.cnblogs.com/RushPasser/p/5438334.html 下载:https://share.weiyun.com/5rM4FrG mysql-for-v ...
- python-中缀转换后缀并计算
这个好像比较简单. 前缀规则好像还没有理清楚. # coding = utf-8 class Stack: def __init__(self): self.items = [] # 是否为空 def ...
- 来一个使用sysbench测试cpu性能的简单脚本
#!/bin/bash for ((i=1; i<16; i++)); do sysbench cpu run --cpu-max-prime=10000 --threads=4 --time= ...
- 使用docker方式安装etcd集群,带TLS证书
网上文档也多,安装的时候,还是踩了几个坑. 现在作一个安装记录吧. 1,先作自签名的证书ca-csr.json(为了和k8s共用根证书,可能将信息调为k8s). { "CN": & ...