Manacher模板(O(n)内求最长回文串长度)
转自:https://segmentfault.com/a/1190000008484167
/*
由于回文分为偶回文(比如 bccb)和奇回文(比如 bcacb),而在处理奇偶问题上会比较繁琐,所以这里我们使用一个技巧,在字符间插入一个字符(前提这个字符未出现在串里)。举个例子:s="abbahopxpo",转换为s_new="$#a#b#b#a#h#o#p#x#p#o#"(这里的字符 $ 只是为了防止越界,下面代码会有说明),如此,s 里起初有一个偶回文abba和一个奇回文opxpo,被转换为#a#b#b#a#和#o#p#x#p#o#,长度都转换成了奇数。
定义一个辅助数组int p[],p[i]表示以s_new[i]为中心的最长回文的半径,例如:
| i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| s_new[i] | $ | # | a | # | b | # | b | # | a | # | h | # | o | # | p | # | x | # | p | # | o | # |
| p[i] | 1 | 2 | 1 | 4 | 5 | 2 | 1 | 2 | 1 | 2 | 1 | 2 | 1 | 2 | 1 | 6 | 1 | 2 | 1 | 2 | 1 |
可以看出,p[i]-1正好是原字符串中最长回文串的长度。
Manacher算法之所以快,就快在对 p 数组的求法上有个捷径。在我们解决了奇偶回文的繁琐时,剩下的难点就是求 p 数组,按照普通思维,我们是这样求解的:求解p[i],先初始化p[i]=1,再以s_new[i]为中心判断两边是否相等,相等就p[i]++。这就是普通的思维,但是我们想想,能否让p[i]的初始化不是 1,让它更大点,看下图:

设置两个变量,mx 和 id 。
mx 代表以s_new[id]为中心的最长回文最右边界,也就是mx=id+p[id]。
假设我们现在求p[i],也就是以s_new[i]为中心的最长回文半径,如果i<mx,如上图,那么:
if (i < mx)
p[i] = min(p[2 * id - i], mx - i);
2 * id -i其实就是等于 j ,p[j]表示以s_new[j]为中心的最长回文半径,见上图,因为 i 和 j 关于 id 对称,我们利用p[j]来加快查找。
*/
时间复杂度:O(n)
应用:
求最长回文串长度
求原串以每个字符为中心的奇数长度回文串的长度
代码如下:
//S用来放原串,CS用来放新串
char S[maxn],CS[maxn<<1];
int P[maxn];
int Init(){
int len=strlen(S);
CS[0]='$';
CS[1]='#';
int cnt=2;
for(int i=0;i<len;i++){
CS[cnt++]=S[i];
CS[cnt++]='#';
}
CS[cnt]='\0';
return cnt;
}
int Manacher(){
int len=Init();
int ans=-1;
int id,mx=0;
for(int i=1;i<len;i++){
if(i<mx) P[i]=min(P[2*id-i],mx-i);
else P[i]=1;
while(CS[i-P[i]]==CS[i+P[i]]) P[i]++;
if(mx<i+P[i]){
id=i;
mx=i+P[i];
}
ans=max(ans,P[i]-1);
}
return ans;
}
Manacher模板(O(n)内求最长回文串长度)的更多相关文章
- UVa 11404 回文子序列(LCS求最长回文串长度)
https://vjudge.net/problem/UVA-11404 题意: 给定一个由小写字母组成的字符串,删除其中的0个或多个字符,使得剩下的字母(顺序不变)组成一个尽量长的回文串.如果有多解 ...
- 字符串的最长回文串:Manacher’s Algorithm
题目链接:Longest Palindromic Substring 1. 问题描述 Given a string S, find the longest palindromic substring ...
- Manacher's Algorithm 马拉车算法(求最长回文串)
作用:求一个字符串中的最长子串,同时还可以求所有子串的长度. 题目链接: https://vjudge.net/contest/254692#problem/B 最长回文串长度的代码: int Man ...
- (最长回文串 模板) 最长回文 -- hdu -- 3068
http://acm.hdu.edu.cn/showproblem.php?pid=3068 最长回文 Time Limit: 4000/2000 MS (Java/Others) Memory ...
- manacher 算法(最长回文串)
manacher算法: 定义数组p[i]表示以i为中心的(包含i这个字符)回文串半径长 将字符串s从前扫到后for(int i=0;i<strlen(s);++i)来计算p[i],则最大的p[i ...
- Manacher(最长回文串)
http://acm.hdu.edu.cn/showproblem.php?pid=3068 最长回文 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符 ...
- ACM题目————最长回文串
Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组cas ...
- Manacher算法 - 求最长回文串的利器
求最长回文串的利器 - Manacher算法 Manacher主要是用来求某个字符串的最长回文子串. 不要被manacher这个名字吓倒了,其实manacher算法很简单,也很容易理解,程序短,时间复 ...
- HDU 3068 最长回文 (Manacher最长回文串)
Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.回文就是正反读都是一样的字符串,如aba, abba等 Input 输 ...
随机推荐
- Codeforces 364E 分治
题意:给你一个01矩阵,问此矩阵有多少个和恰好为k的子矩形. 思路:分治,对于当前矩形,用一条中线把矩形分成两半,分治之后计算跨过中线的矩形个数.更具体的来说(假设划了一条水平中线),我们枚举矩形左右 ...
- Devops、CI\CD、Jenkins
Devops DevOps对应用程序发布的影响 在很多企业中,应用程序发布是一项涉及多个团队.压力很大.风险很高的活动.然而在具备DevOps能力的组织中,应用程序发布的风险很低,原因如下 [2] : ...
- redis相关笔记(三.redis设计与实现(笔记))
redis笔记一 redis笔记二 redis笔记三 1.数据结构 1.1.简单动态字符串: 其属性有int len:长度,int free:空闲长度,char[] bur:字符数组(内容) 获取字符 ...
- Delphi 字符串函数SysUtils单元 AnsiSameStr、AnsiSameText、AnsiCompareStr、AnsiCompareText、AnsiCompareFileName、AnsiUpperCase、AnsiLowerCase、AnsiUpperCaseFileName、AnsiLowerCaseFileName、AnsiPos、AnsiQuotedStr
USES 单元 SysUtils 非 StrUtils AnsiSameStr.AnsiSameText.AnsiCompareStr.AnsiCompareText.AnsiCompareFileN ...
- 服务化改造的云上利器 | 阿里云 EDAS 重大升级发布
11月22日,广东云栖大会企业级互联网架构专场上,阿里云发布了全新版本的企业级分布式应用服务EDAS. 新版本增强了对主流微服务框架的原生支持,实现SpringCloud & Dubbo用户代 ...
- ceph cache pool配置
https://my.oschina.net/hanhanztj/blog/515410 0.引入 本文介绍如何配置cache pool tiering. cache pool的作用是提供可扩展的ca ...
- AcWing 214. Devu和鲜花 (容斥)打卡
Devu有N个盒子,第i个盒子中有AiAi枝花. 同一个盒子内的花颜色相同,不同盒子内的花颜色不同. Devu要从这些盒子中选出M枝花组成一束,求共有多少种方案. 若两束花每种颜色的花的数量都相同,则 ...
- [NOIP模拟测试30]题解
A.Return 出题人大概是怕自己的中文十级没人知道,所以写了这么一个***题面.可能又觉得这题太水怕全场A掉后自己面子过不去,于是又故意把输出格式说的含糊不清.(鬼知道"那么输出-1&q ...
- 【Spring Boot】Spring Boot项目部署到外部Tomcat容器
一.修改项目打包方式为war包 修改pom.xml文件中packaging属性项 <packaging>war</packaging> 修改pom.xml文件增加一个依赖 &l ...
- PHP 换行处理
换行符 unix系列用 \n windows系列用 \r\n mac用 \r PHP中可以用PHP_EOL来替代,以提高代码的源代码级可移植性 如: <?php echo PHP_EOL; // ...