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 同时可以由这个翻倍的 ...
随机推荐
- Soat控制HAProxy 动态增减服务器
Soat控制HaProxy 动态增减服务器 安装HaProxy-1.5.18: yum install haproxy -y yum install socat -y HaProxy-1.5.18 配 ...
- 使用Jenkins+Pipline 持构建自动化部署之安卓源码打包、测试、邮件通知
一.引言 Jenkins 2.x的精髓是Pipeline as Code,那为什么要用Pipeline呢?jenkins1.0也能实现自动化构建,但Pipeline能够将以前project中的配置信息 ...
- SQL注入-流程
一般注入分类: 时间,布尔,报错,堆,联合 有关函数介绍: current_user() 当前用户名 session_user() 链接数据库的用户名 @@basedir mysql安装路径 @@da ...
- rename 表名
rename table 旧表名1 to 新表名1,旧表名2 to 新表名2;
- WIN7系统没有USB驱动和以太网驱动如何操作
| 欢迎关注个人公众号 zclinux_note 第一时间获取关于linux使用的技巧.探索Linux的奥秘 | 今天在单位安装了一台win7纯净版,但是安装完成后发现usb没有反应,插上网 ...
- ctfhub技能树—信息泄露—hg泄露
打开靶机 查看页面信息 使用dvcs-ripper工具进行处理 ./rip-hg.pl -v -u http://challenge-cf630b528f6f25e2.sandbox.ctfhub.c ...
- RWCTF2020 DBaaSadge 复现
数据库题目 2020RWCTF DBaaSadge WP 这是一个很有意思的题目,难到让我绝望,跟着大佬smity的思路跑一下,求大佬抱抱. https://mp.weixin.qq.com/s/jv ...
- 快速查询表中的NULL数据
正常情况下,NULL值是不会放入B-TREE索引的,因此根据IS NULL查询的时候走的通常是全表扫描,如果记录比较少还好,记录比较多,查询会非常耗时 可以通过创建一个索引来解决 CREATE IND ...
- 机器学习7-模型保存&无监督学习
模型保存和加载 sklearn模型的保存和加载API from sklearn.externals import joblib 保存:joblib.dump(rf, 'test.pkl') 加载:es ...
- tf
第2章 Tensorflow keras实战 2-0 写在课程之前 课程代码的Tensorflow版本 大部分代码是tensorflow2.0的 课程以tf.kerasAPI为主,因而部分代码可以在t ...