manacher算法可以解决字符串的回文子串长度问题。

个人感觉szy学长讲的非常好,讲过之后基本上就理解了。

那就讲一下个人的理解。(参考了szy学长的ppt)

如果一个回文子串的长度是偶数,对称轴会落在两个字符中间。

首先两个字符中间的这个位置就很难表示。

所以我们在两个字符中间加上没有用的字符,比如说'#'。开头结尾也加上。

例如:abcba --> #a#b#c#b#a#

这样我们能很方便的表示每一个位置。

manacher算法最终的目的是求出一个数组pl[i],代表以i为回文中心(也就是对称轴)的最长回文子串的回文半径。

回文半径指的是回文子串的长度除以二之后向上取整。

比如:#a#b#a#的回文半径就是4。

考虑用递推的方法求出pl数组。

首先我们知道pl[1]=1(特殊记一下)。

在递推的过程中维护一个np表示使i+pl[i]最大的一个i。

计算f[i]的时候,先考虑使用已知的信息求出f[i]。

如果i<=np+pl[np],意味着i被以np为回文中心的最长回文子串“覆盖”了。

下面的图用红色表示以np为回文中心的最长回文子串,用绿色表示以i为回文中心的最长回文子串。

这时有两种情况:

1.不仅i被覆盖,以i为回文中心的最长回文子串也被完全覆盖了。

这个时候由于对称性,pl[i]=pl[2*np-i]。

2.虽然i被覆盖,但是以i为回文中心的最长回文子串没有被完全覆盖。

这个时候我们只能保证np+pl[np]以内的对称性(蓝色部分)。

也就是说,pl[i]=pl[np]+np-i。

我们并不知道是哪种情况,所以只能对这两种情况分别求值并取其中的最小值。

之后如果还能继续向外拓展回文部分,就类似暴力的做法,一下一下向外拓展。

最后更新一下np。

求出的pl是适用于新串的(就是混了一堆‘#’的那个串)。

不难发现,对于原串,以i为中心的最长回文子串的长度为pl[i]-1,这个串的开始位置为(i-pl[i])/2+1(向下取整)。

来一道模板题练练:洛谷 P3805 【模板】manacher算法

题目传送门

这里不得不说,szy学长给的代码真是又简洁又明了。

吊打网上那些参杂各种特判的冗长又难读的代码。

膜拜orz。

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; int n;
char a[];
char s[];
int pl[]; int main()
{
scanf("%s",a+);
int al=strlen(a+);
for(int i=;i<=al;i++)
s[++n]='#',s[++n]=a[i];
s[++n]='#';
int np=;
pl[]=;
for(int i=;i<=n;i++)
{
pl[i]=min(pl[*np-i],pl[np]+np-i);
for(;i+pl[i]<=n&&s[i+pl[i]]==s[i-pl[i]];pl[i]++);
if(i+pl[i]>np+pl[np])np=i;
}
int ans=;
for(int i=;i<=n;i++)ans=max(ans,pl[i]-);
printf("%d",ans);
return ;
}

manacher算法 详解+模板的更多相关文章

  1. manacher算法详解+模板 P3805

    前言: 记住manacher是一个很简单的算法. 首先我们来了解一下回文字串的定义:若一个字符串中的某一子串满足回文的性质,则称其是回文子串.(注意子串必须是连续的,而子序列是可以不连续的) 那么若给 ...

  2. 算法进阶面试题01——KMP算法详解、输出含两次原子串的最短串、判断T1是否包含T2子树、Manacher算法详解、使字符串成为最短回文串

    1.KMP算法详解与应用 子序列:可以连续可以不连续. 子数组/串:要连续 暴力方法:逐个位置比对. KMP:让前面的,指导后面. 概念建设: d的最长前缀与最长后缀的匹配长度为3.(前缀不能到最后一 ...

  3. Manacher算法详解

    问题 什么是回文串,如果一个字符串正着度读和反着读是一样的,这个字符串就被称为回文串. such as noon level aaa bbb 既然有了回文,那就要有关于回文的问题,于是就有了-- 最长 ...

  4. 经典算法 Manacher算法详解

    内容: 1.原始问题   =>O(N^2) 2.Manacher算法   =>O(N) 1.原始问题 Manacher算法是由题目“求字符串中长回文子串的长度”而来.比如 abcdcb 的 ...

  5. [转] Manacher算法详解

    转载自: http://blog.csdn.net/dyx404514/article/details/42061017 Manacher算法 算法总结第三弹 manacher算法,前面讲了两个字符串 ...

  6. hdu3068之manacher算法+详解

    最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  7. KM算法详解+模板

    http://www.cnblogs.com/wenruo/p/5264235.html KM算法用来求二分图最大权完美匹配. 本文配合该博文服用更佳:趣写算法系列之--匈牙利算法 现在有N男N女,男 ...

  8. KM算法 详解+模板

    先说KM算法求二分图的最佳匹配思想,再详讲KM的实现.[KM算法求二分图的最佳匹配思想] 对于具有二部划分( V1, V2 )的加权完全二分图,其中 V1= { x1, x2, x3, ... , x ...

  9. KMP算法 详解+模板

    本文大部分摘自szy学长的ppt<string>中的KMP部分. %%%膜拜szy大神orz 1.概述 KMP 算法是用来解决单模匹配问题的一种算法. 如果暴力的进行单模匹配,那么时间复杂 ...

随机推荐

  1. LeetCode——973. 最接近原点的 K 个点

    我们有一个由平面上的点组成的列表 points.需要从中找出 K 个距离原点 (0, 0) 最近的点. (这里,平面上两点之间的距离是欧几里德距离.) 你可以按任何顺序返回答案.除了点坐标的顺序之外, ...

  2. POJ-2561 Network Saboteur(DFS)

    题目: A university network is composed of N computers. System administrators gathered information on t ...

  3. 关于 TCP 和 UDP 协议

    TCP\UDP 两者区别总结:https://blog.csdn.net/striveb/article/details/84063712 图解HTTP,状态码,TCP.UDP等网络协议相关总结(持续 ...

  4. 剑指offer【13】- 链表中倒数第k个结点

    输入一个链表,输出该链表中倒数第k个结点. /* public class ListNode { int val; ListNode next = null; ListNode(int val) { ...

  5. 二、Shell脚本高级编程实战第二部

    一.什么是变量? 变量就是一个固定的字符串替代更多更复杂的内容,当然内容里面可能还有变量.路径.字符串等等内容,最大的特点就是方便,更好开展工作 1.变量有环境变量(全局变量)和局部变量 环境变量就是 ...

  6. SALESORDERINCOME.QVW

    //销售订单SALESORDER_BASE_TMP:NoConcatenateLOAD T_SAL_ORDER.LE_ID, [T_SAL_ORDER.LCY CODE], T_SAL_ORDER.S ...

  7. Netty之内存泄露

    直接内存是IO框架的绝配,但直接内存的分配销毁不易,所以使用内存池能大幅提高性能. 1.为什么要有引用计数器 Netty里四种主力的ByteBuf,其中UnpooledHeapByteBuf底下的by ...

  8. Java--java中的基本数据类型以及对应的包装类

    基本数据类型 序号 数据类型 长度(位数) 默认值 1 byte(整数型) 8 0 2 short(整数型) 16 0 3 int(整数型) 32 0 4 long(整数型) 64 0 5 float ...

  9. MTSP问题

    问题描述:m个旅行商去旅游 n个城市,规定都必须从同一个出发点出发,而且返回原出发点,需要将所有的城市遍历完毕,每个城市只能游历一次,但是为了路径最短可以路过这个城市多次.这个就是多旅行商问题.是在T ...

  10. LeetCode No.127,128,129

    No.127 LadderLength 单词接龙 题目 给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度.转换需遵 ...