manacher算法详解
例题
- 求一个字符串的最长回文子串的长度
O(N2)O(N^2)O(N2)的解法很容易想,就是从每个字符位置向左右同时拓展,然后检查当前是不是回文,更新长度,可以简单写一下代码
int solve(string &ss){int ans = 0;int n = ss.length();string s;s.resize(2 * n + 1);int l = 0;s[l++] = '$';s[l++] = '#';for(int i=0;i<n;i++){s[l++] = ss[i];s[l++] = '#';}for(int i=0;i<l;i++){int p = 0;while(i - p >= 0 && i + p < l && s[i + p] == s[i - p]){p += 1;}ans = max(ans, p - 1);}return ans;
}
- 这里注意一个小技巧,一个字符串有两种情况,分别是长度为奇数和长度为偶数,如何将这两种情况归一化呢?考虑在字符串前面加一个$,在每两个字符之间放一个#,不一定非得是$和#,只要不会在字符串中出现即可,容易计算得到这样做得到的字符串长度一定是奇数
- 考虑优化,容易想到如果计算已经得到了前面的回文半径(以某个字符为中心的回文串长度的一半),那么对称的两个点中尚未计算的那个点的回文半径的最小值也就是已经计算得到的那个点的回文半径

- 观察上面的字符串,第一个红色的b的回文半径容易求出是2,后面的c的回文半径容易求出是6,那么我们如何根据它求出后面的红色的b的回文半径呢?显然因为c的回文半径范围覆盖了第一个红色的b,所以第二个红色的b的回文半径的最小值是第一个红色的b的回文半径(这里同时因为c的回文半径也覆盖了第二个红色的b的回文半径区域,因为如果第二个红色的b之后没有足够的字符也是到不了第一个红色的b的回文半径的),这样我们就得到了第二个b的回文半径的最小值,然后暴力拓展,就为之后的字符串也做好了铺垫,可以证明总的时间复杂度是O(n)O(n)O(n)的
- 上面是我对manacher算法的个人理解,接下来从代码的角度来说一下,首先需要两个变量
r和c,因为有一个问题,怎么判断某个字符是不是在某个回文区间之内,我们可以从左边递推找到一个右端点最远的回文区域,这样记录一下中心端点c和右端点r,在从左到右计算的过程中更新最大的r,这样就找到了回文半径和回文中心 - 然后使用一个数组
P[i]记录以i为中心的回文半径,具体代码如下
int manacher(string &ss){int n = ss.length();string s;s.resize(2 * n + 1);int l = 0;s[l++] = '$';s[l++] = '#';for(int i=0;i<n;i++){s[l++] = ss[i];s[l++] = '#';}vector<int> P(l);int r, c;r = c = 0;int ans = 0;for(int i=0;i<l;i++){int &p = P[i];// 用r - i约束的原因上面已经说过p = (i + p < r ? min(r - i, P[2 * c - i]) : 1);// 2 * c - i是对称位置的字符while(s[i + p] == s[i - p]) p += 1;if(i + p > r){r = i + p;c = i;}ans = max(ans, p - 1);}return ans;
}
例题
https://www.luogu.com.cn/problem/P4287
在一个字符串里面找前后两个长度相等的子串都是回文串的字符串的最大长度
- 考虑manacher,如果计算出了一个回文串,因为它的前面已经计算好了,比如现在回文半径右端点最远在rrr,那么从iii到rrr这一段是回文串的一半我们是知道的,现在考虑它前面一段,怎么考虑呢?根据对称性,设j≥rj\geq rj≥r,对称到左边就是i−j−i2i-\frac{j-i}{2}i−2j−i同时还需要满足(j−i)%4=0(j-i)\%4=0(j−i)%4=0,这里的iii是右侧字符串的回文中心,jjj是左侧字符串关于ccc对称的回文中心
- 因为要求这样的回文串长度必须是偶数,所以根据我们的回文串构造方法,每次枚举的iii必须是奇数
#include <bits/stdc++.h>using namespace std;int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int n;string ss;cin >> n >> ss;string s;s.resize(2 * n + 1);int l = 0;s[l++] = '$';s[l++] = '#';for(int i=0;i<n;i++){s[l++] = ss[i];s[l++] = '#';}vector<int> P(l);int r, c;r = c = 0;int ans = 0;for(int i=0;i<l;i++){int &p = P[i];p = (i + p < r ? min(P[2 * c - i], r - i) : 1);while(s[i + p] == s[i - p]) p += 1;if(i + p > r){if(i & 1){for(int j=max(r, i + 4);j<=i+p;j++){if((j - i) % 4 == 0 && P[i - (j - i) / 2] >= (j - i) / 2){ans = max(ans, j - i);}}}r = i + p;c = i;}}cout << ans << '\n';return 0;
}
相关文章:
manacher算法详解
例题 求一个字符串的最长回文子串的长度 O(N2)O(N^2)O(N2)的解法很容易想,就是从每个字符位置向左右同时拓展,然后检查当前是不是回文,更新长度,可以简单写一下代码 int solve(string &ss){int ans 0;int n ss.length();s…...
要做一个关于DDD的内部技术分享,记录下用到的资源,学习笔记(未完)
最后更新于2023年3月10日 14:28:08 问题建模》软件分层》具体结构,是层层递进的关系。有了问题建模,才能进行具体的软件分层的讨论,再有了分层,才能讨论在domain里面应该怎么实现具体结构。 1、问题建模:Domain、Mod…...
KDZD互感器二次负载测试仪
一、概述 电能计量综合误差过大是电能计量中普遍存在的一个关键问题。电压互感器二次回路压降引起的计量误差往往是影响电能计量综合误差的因素。所谓电压互感器二次压降引起的误差,就是指电压互感器二次端子和负载端子之间电压的幅值差相对于二次实际电压的百分数…...
在空投之后,Blur能否颠覆OpenSea的主导地位?
Mar. 2023, Daniel数据源: NFT Aggregators Overview & Aggregator Statistics Overview & Blur Airdrop一年前,通过聚合器进行的NFT交易量开始像滚雪球一样增长,有时甚至超过了直接通过市场平台的交易量。虽然聚合器的使用量从10月到…...
2023年新三板产品及服务研究报告
第一章 概述 全国中小企业股份转让系统(英语:National Equities Exchange and Quotations,缩写NEEQ),简称股转系统,是第三家全国性证券交易场所,因挂牌企业均为高科技企业而不同于原转让系统内…...
张力控制之开环模式
张力控制的相关知识也可以参看专栏的其它文章,链接如下: 张力闭环控制之传感器篇(精密调节气阀应用)_RXXW_Dor的博客-CSDN博客跳舞轮对应张力调节范围,我们可以通过改变气缸的气压方式间接改变,张力跳舞轮在收放卷闭环控制上的详细应用,可以参看下面的文章链接,这里我…...
python的django框架从入门到熟练【保姆式教学】第二篇
在上一篇博客中,我们介绍了Django的基础知识,并创建了一个简单的Web应用程序。在本篇教程中,我们将深入探讨Django的模型层(Model),它是Django应用程序的核心组件之一。 模型层 Django的模型层是一个对象…...
解决win10的过度保护导致文件下载不了程序不能打开运行
win7看来大概是要离我们远去了,虽然我们还能看见她的背影,但大势所趋,我们也只能慢慢的接受win10进入到我们的日常生活。但win10很多时候过度的保护却给我们带来了不便。这里列举两个最常见的问题,当然我这里也给出了解决方案。 文…...
扬帆优配|业务量大突破,这个行业发展明显向好
近期上市的新股,大都在招股阐明书里公布了本年第一季度成绩预告。 我国快递事务量本年已达200亿件 国家邮政局监测数据显现,到3月8日,本年我国快递事务量已到达200.9亿件,比2019年到达200亿件提前了72天,比2022年提前…...
DJ1-4 计算机网络和因特网
目录 一、协议层及其服务模型 ISO/OSI 七层参考模型 TCP/IP 参考模型 1. 网际协议栈(protocol stack) 2. 分层:逻辑通信 3. 协议分层与数据 二、攻击威胁下的网络 1. 植入恶意软件 2. 攻击服务器和网络基础设施 3. 嗅探分组 4. 伪…...
Nginx根据$host及请求的URI规则重定向rewrite
项目背景: 将域名请求从默认的80端口转发到443 ssl。本项目特殊之处是一个端口监听多个域名,某些域名还有跳转到特定的地址。 普通情况: server { listen 80; #默认的80端口,非…...
人工智能实验一:使用搜索算法实现罗马尼亚问题的求解
1.任务描述 本关任务: 了解有信息搜索策略的算法思想;能够运用计算机语言实现搜索算法;应用A*搜索算法解决罗马尼亚问题; 2.相关知识 A*搜索 算法介绍 A*算法常用于 二维地图路径规划,算法所采用的启发式搜索可以…...
Spring Security基础入门
基础概念 什么是认证 认证:用户认证就是判断一个用户的身份身份合法的过程,用户去访问系统资源的时候系统要求验证用户的身份信息,身份合法方可继续访问,不合法则拒绝访问。常见的用户身份认证方式有:用户密码登录&am…...
dnsresolver-limit
文件OperationLimiter.h功能DnsResolver是andnroid中提供DNS能力的小型DNS解析器,limit是其中的一个小模块,支持全局、基于key(UID)的DNS请求限制。DnsResolver是多线程模型,单个DNS请求最多启动3个线程(传统DNS)。在网…...
使用 YoctoProject集成Qt6
By Toradex胡珊逢在嵌入式领域中Qt 作为普遍选择的 UI 方案目前已经发布 Qt6 版本。本文将介绍如何为 Toradex 的计算机模块使用 Yocto Project 将 Qt6 集成到镜像里。首先根据这里的说明,准备好Yocto Project 的编译环境。这里我们选择 Toradex 最新的 Linux BSP V…...
「媒体邀约」如何选择适合的媒体公关,媒体服务供应商
传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 每天胡老师也会接到大量关于媒体方面的询问,胡老师也都一一的很耐心的进行了解答,也都很详细的做了媒体规划和媒体传播方案,但有的朋友还是很犹豫&…...
html2canvas和jspdf导出pdf,每个页面模块占一页,在pdf中垂直居中显示
需求:html页面转换pdf,页面有多个模块,页面中有文本、echarts、表格等模块,一个模块占一页,因为模块高度不够,所以需要垂直居中 通过html2canvas和jspdf实现,html2canvas用于将页面元素生成canv…...
数学小课堂:集合论的公理化过程(用构建公理化体系的思路来构建自然数)
文章目录 引言I 数的理论1.1 构建自然数1.2 定义整数/有理数/实数/虚数/复数II 自然数和集合的关系1.3 集合1.2 构建自然数III 线性规划问题(线性代数+最优化)3.1 题目3.2 答案引言 数学是一个公理化的体系,是数学对其它知识体系有启发的地方。 数学的思维方式: 不轻易相信…...
3.10多线程
一.常见锁策略1.悲观锁 vs乐观锁体现在处理锁冲突的态度①悲观锁:预期锁冲突的概率高所以做的工作更多,付出的成本更多,更低效②乐观锁:预期锁冲突的概率低所以做的工作少,付出的成本更低,更搞笑2.读写锁 vs 普通的互斥锁①普通的互斥锁,只有两个操作 加锁和解锁只有两个线程针…...
缓存双写一致性之更新策略探讨
问题由来 数据redis和MySQL都要有一份,如何保证两边的一致性。 如果redis中有数据:需要和数据库中的值相同如果redis中没有数据:数据库中的值是最新值,且准备会写redis 缓存操作分类 自读缓存读写缓存: ࿰…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
