manacher算法——回文串计算的高效算法
manacher算法的由来不再赘述,自行百度QWQ。。。
进入正题,manacher算法是一个高效的计算回文串的算法,回文串如果不知道可以给出一个例子:“ noon ”,这样应该就很清晰了;
其实这个算法虽然名字长,但是实际代码很短,而且理解起来并不难。。。(连我这种蒟蒻都懂了)
这里给出模板题
题目描述
给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
字符串长度为n
输入格式
一行小写英文字符a,b,c...y,z组成的字符串S
输出格式
一个整数表示答案
其中n的范围为11000000,很显然,只能是O(n)的复杂度,但是为何复杂度这么优秀,这里在讲完算法之后会简述。
定理:
- 一个回文串只有一个对称中心,这个中心上可能有字母或者没有(如果没有字母,我们可以再加上一个,再后面会解释),我们暂且定义其为mid;
- mid两端的区间对称,两边全等(回文串的定义);
- 如果一个大的回文串一端的区间中有回文串,我们先定义它的中心为 i ,那么大回文串的另一端一定会有相同的回文串;
- 根据上一条,如果我们要更新在右端区间的回文串,那么在左边的回文串半径就可以更新右边的,但是有大回文串的区间限制,所以应当两者取min;
- 结束上面定理的继承之后,直接暴力枚举检查是否两端更新。
解释:
上面的原理毕竟太过干,只是纯理论,所以制图说明;

比如说这个区间是一个大回文串,我们我们用r保留其有边界,那么l就可以根据中点坐标公式变形得到mid*2 - r,所以我们只保留右边界 r 即可。
那么可以看见,如果我们以 i 为这段区间中一个回文串的中心,那么,与它对称的回文串中心就可以求出(根据中点公式,得2*mid - i ,与上面相同);
那么我们就可以根据定理来继承左边回文串的半径,但是如果左边这个回文串有超过区间的部分怎么办?
这里就用到我们所说的取min了,将左边回文串半径和r - i相比取min,这里就得到了 i 的一个半径,但这个半径一定小于或等于真实半径,所以还需暴力枚举;
这里就可见manachar算法的核心操作了,就是枚举回文串中心,然后继承半径以来减少枚举的次数;
我们用p[ i ]表示以点 i 为中心的回文串的半径,r记录回文串到达的最右边的坐标,mid随之更新,记录这个回文串的中心;
Code
#include<bits/stdc++.h>
#define maxn 22000007
using namespace std;
char dat[maxn];
int p[maxn],r,cnt=1,mid,ans; void scan(){
char s=getchar();
dat[0]='~';//为了不超出边界的小操作
dat[1]='|';//这个间隔解决了对称中心没有字母的情况
while(s>='a'&&s<='z'){
dat[++cnt]=s;
dat[++cnt]='|';
s=getchar();
}//其实与读入优化没差啦
}//自定义读入 int main(){
scan();
for(int i=2;i<=cnt;i++){
if(r>i) p[i]=min(p[2*mid-i],r-i);//由对称的回文串继承,用r-i限制
else p[i]=1;//CASE :无法继承
while(dat[i-p[i]]==dat[i+p[i]]) p[i]++;//暴力更新
if(p[i]+i>r) r=p[i]+i,mid=i;// r边界必须是最右
ans=max(ans,p[i]);//更新答案
}
printf("%d\n",ans-1);//这个减一可以自己模拟一下,数学推了话好麻烦的说
}
这就是manachar算法的简述了,当然这里解释一下为什么复杂度为O(n):
我感觉这和KMP复杂度有些类似,因为这里因为继承的缘故,所以每个点更新次数较少,然后均摊到每个循环,那么复杂度就变成了O(n)了;
manacher算法——回文串计算的高效算法的更多相关文章
- Girls' research - HDU 3294 (Manacher处理回文串)
题目大意:给以一个字符串,求出来这个字符串的最长回文串,不过这个字符串不是原串,而是转换过的,转换的原则就是先给一个字符 例如 'b' 意思就是字符把字符b转换成字符 a,那么c->b, d-& ...
- leetcode:Palindrome Number (判断数字是否回文串) 【面试算法题】
题目: Determine whether an integer is a palindrome. Do this without extra space. Some hints: Could neg ...
- hdu 3294 manacher 求回文串
感谢: http://blog.csdn.net/ggggiqnypgjg/article/details/6645824/ O(n)求给定字符串的以每个位置为中心的回文串长度. 中心思想:每次计算位 ...
- HDU 5340——Three Palindromes——————【manacher处理回文串】
Three Palindromes Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...
- HDU 5371 Hotaru's problem (Manacher,回文串)
题意:给一个序列,找出1个连续子序列,将其平分成前,中,后等长的3段子序列,要求[前]和[中]是回文,[中]和[后]是回文.求3段最长为多少?由于平分的关系,所以答案应该是3的倍数. 思路:先Mana ...
- 算法 -- 四种方法获取的最长“回文串”,并对时间复杂进行分析对比&PHP
https://blog.csdn.net/hongyuancao/article/details/82962382 “回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就 ...
- 2015 UESTC Training for Search Algorithm & String - M - Palindromic String【Manacher回文串】
O(n)的复杂度求回文串:Manacher算法 定义一个回文值,字符串S是K重回文串,当且仅当S是回文串,且其长度为⌊N/2⌋的前缀和长度为⌊N/2⌋的后缀是K−1重回文串 现在给一个2*10^6长度 ...
- 最长回文子串问题 O(n)算法 manacher URAL1297 HDU3068
先来看一道简单的题,ural1297 给定一个1000长度的字符串,求最长回文子串. 看起来很Naive,乱搞一下,O(n^2)都可以解决. 再来看这个题 HDU3068 120个110000长度的字 ...
- 马拉车,O(n)求回文串
马拉车,O(n)求回文串 对整个马拉车算法步骤做个总结: 第一步:将每个原字母用两个特殊字符包围如: aaa --> #a#a#a# abab -->#a#b#a#b 同时可以由这个翻倍的 ...
随机推荐
- 【SpringMVC】SpringMVC 拦截器
SpringMVC 拦截器 文章源码 拦截器的作用 SpringMVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理. 谈到拦截器,还有另外一个概 ...
- 前端面试:Http协议与浏览器
Http与Https的区别 Http是明文传输的,Https协议是在Http协议上添加了SSL的加密协议,可以进行加密传输和身份验证. 其实就是说Http对网络传输完全是裸奔状态,也就没办法防范中间人 ...
- 【Java】一个简单的Java应用程序
简单记录,Java 核心技术卷I 基础知识(原书第10 版) 一个简单的Java应用程序"Hello, World!" Hello, World! Goodbye,World! 一 ...
- 【MySQL】Last_SQL_Errno: 1594Relay log read failure: Could not parse relay log event entry...问题总结处理
备库报错: Last_SQL_Errno: 1594 Last_SQL_Error: Relay log read failure: Could not parse relay log event e ...
- 【Linux】tcpdump
tcpdump介绍 tcpdump 是一个运行在命令行下的抓包工具.它允许用户拦截和显示发送或收到过网络连接到该计算机的TCP/IP和其他数据包.tcpdump 适用于 大多数的类Unix系统操作系统 ...
- oracle rac切换到单实例DG后OGG的处理
在RAC切换到单实例DG后,将OGG目录复制过去,在使用alter extract ext_name,begin now的时候报错 2016-04-10 11:27:03 WARNING OGG-01 ...
- oracle move表空间(分区表,索引)
1.修改分区表分区表空间 SELECT 'ALTER TABLE ' || table_owner || '.' || TABLE_NAME || ' MOVE PARTITION ' || PART ...
- SEO大杀器rendertron安装
前段时间做SEO的优化,使用的是GoogleChrome/rendertron,发现这个安装部署的时候还是会有一些要注意的地方,做个记录 为什么要使用rendertron 目前很多网站都是使用 vue ...
- 扩展:Flash消息
扩展:Flash消息 flash存值之后只能取一次 from flask import Flask,render_template,flash,get_flashed_messages,session ...
- ORB-SLAM2-tracking线程
tracking线程 Tracking线程的主要工作是从图像中提取ORB特征,根据上一帧进行姿态估计或者进行通过全局重定位初始化位姿,然后跟踪已经重建的局部地图,优化位姿,再根据一些规则确定新的关键帧 ...