Manacher算法讲解

总有人喜欢搞事情,出字符串的题,直接卡掉了我的40分

I.适用范围

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

关键词:最长 回文 子串

II.算法

1.纯暴力怎么写?

枚举每个字串(n^2)

判断是否回文(n)

综上,时间为n^3。

能解决n < 300的数据

2.优化的暴力

枚举点(n)

从点开始向两边逐个扩展,统计回文串的长度(上界n,但随机情况下很小)

综上,时间为n^2。

在随机数据下,实际表现能达到大概(n^2 / logn)的速度。

能解决5000左右的数据。

我们定义回文串的半径为回文串的回文中心到回文串的一端中间有多少个字符(不包含中心,包含端点)

比如回文串floatiyyitaolf的半径就是7,而vanav的半径是2。

对于长度是奇数和偶数的串要分类讨论。

给个示意的代码:

for(int i = ;i <= n;i++) {
回文串的半径 k = ;
while(s[i-k] == s[i+k]) k++;
ans = max(k*+,ans);
}

3.更优秀的算法——manacher

manacher可以看作是对上面那个n^2算法的进一步优化。

在枚举点统计回文串的过程中,我们其实是计算出了一些有用的信息,这些信息可以被后面的点使用,而无需重复计算(跟kmp有点像?)。

具体来说,我们从左向右枚举点,每次记录一下以这个点为中心的最长回文子串的半径(以i为中心的最长半径记为p[i])。

我们要试着利用回文的性质,因为子串是回文的,所以对于任意一个点x,有s[x - k] = s[x + k]  (k<= p[x])。这条性质可以省去重复比较字符的过程。

manacher的算法流程:

记录现在最大的(p[i] + i)为maxright,maxright对应的i为pos。

枚举下一个位置i时,i与maxright和pos有下面三种情况:

蓝星星代表i点,褐色星星代表i点关于pos的对称点j。

情况1:

p[j]较小,被p[pos]完全包含,那么由于pos的两边是对称的,那么蓝色区间一定是回文的,我们只要在蓝色区间的基础上再找更大的回文区间就可以了。

情况2:

p[j]较大,但我们只能保证红色区间是回文的,所以情况二中的蓝色区间是回文的,求更大的蓝色回文区间仍需要逐个扩展。

情况3:

此时i已经超出了maxright,不在红色范围,内此时只能逐个扩展。

每次扩展完毕要更新pos和maxright。

manacher还处理了一个问题:字串长度是奇数偶数要分类讨论。

具体方法是在每个字符的前后都保证有一个不在题目给的串里出现的字符,强行转化成奇数个字符。

AAADJ —> #A#A#A#D#J#

Code

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; const int MAXN = + ; int n,ans;
int maxright,pos;
int p[MAXN<<];
char t[MAXN<<],s[MAXN<<]; inline int _max(int x,int y) {
return x > y ? x : y;
} inline int _min(int x,int y) {
return x < y ? x : y;
} int main() {
scanf("%s",t+);
n = strlen(t+);
s[] = '@';
for(register int i = ;i <= n;i++) {
s[i+i-] = '#';
s[i+i] = t[i];
}
n = n+n+; s[n] = '#';
for(register int i = ;i <= n;i++) {
if(i < maxright) p[i] = _min(p[pos+pos-i],maxright-i);
while(s[i-p[i]] == s[i+p[i]]) p[i]++;
ans = _max(ans,p[i]);
if(i+p[i] > maxright) maxright = i+p[i], pos = i;//要及时更新maxright
}
printf("%d\n",ans-);
return ;
}

manacher马拉车算法的更多相关文章

  1. Manacher(马拉车)算法(jekyll迁移)

    layout: post title: Manacher(马拉车)算法 date: 2019-09-07 author: xiepl1997 cover: 'assets/img/manacher.p ...

  2. manacher(马拉车算法)

    Manacher(马拉车算法) 序言 mannacher 是一种在 O(n)时间内求出最长回文串的算法 我们用暴力求解最长回文串长度的时间复杂度为O(n3) 很明显,这个时间复杂度我们接受不了,这时候 ...

  3. HDU - 3068 最长回文manacher马拉车算法

    # a # b # b # a # 当我们遇到回判断最长回文字符串问题的时候,若果用暴力的方法来做,就是在字符串中间添加 #,然后遍历每一个字符,找到最长的回文字符串.那么马拉车算法就是在这个基础上进 ...

  4. Manacher (马拉车) 算法:解决最长回文子串的利器

    最长回文子串 回文串就是原串和反转字符串相同的字符串.比如 aba,acca.前一个是奇数长度的回文串,后一个是偶数长度的回文串. 最长回文子串就是一个字符串的所有子串中,是回文串且长度最长的子串. ...

  5. 最长回文子串 —— Manacher (马拉车) 算法

    最长回文子串 回文串就是原串和反转字符串相同的字符串.比如 aba,acca.前一个是奇数长度的回文串,后一个是偶数长度的回文串. 最长回文子串就是一个字符串的所有子串中,是回文串且长度最长的子串. ...

  6. Manacher(马拉车)算法

    Manacher算法是一个求字符串的最长回文子串一种非常高效的方法,其时间复杂度为O(n).下面分析以下其实行原理及代码: 1.首先对字符串进行预处理 因为回文分为奇回文和偶回文,分类处理比较麻烦,所 ...

  7. [模板] Manacher(马拉车)算法

    用途 求回文子串 做法 先考虑回文子串以某字符为中心的情况,即长度为奇数 推着做,记rad[i]为以i位置为中心的最大半径(包含中点) 考虑怎么求rad[i].找之前的一个右端点最靠右的位置p,设它的 ...

  8. Manacher(马拉车)算法详解

    给定一个字符串,求出其最长回文子串 eg:  abcba 第一步: 在字符串首尾,及各字符间各插入一个字符(前提这个字符未出现在串里). 如  原来ma  /*  a    b a    b   c ...

  9. Manacher's Algorithm 马拉车算法

    这个马拉车算法Manacher‘s Algorithm是用来查找一个字符串的最长回文子串的线性方法,由一个叫Manacher的人在1975年发明的,这个方法的最大贡献是在于将时间复杂度提升到了线性,这 ...

随机推荐

  1. SDK介绍

    软件开发工具包(外语首字母缩写:SDK.外语全称:Software Development Kit)一般都是一些软件工程师为特定的软件包.软件框架.硬件平台.操作系统等建立应用软件时的开发工具的集合. ...

  2. Swift4 协议

    创建: 2018/02/27 完成: 2018/02/28 更新: 2018/03/07 增加类采用协议时的注意 补充只有类, 结构体, 枚举型可以采用协议 增加为类定义准备的协议( protocol ...

  3. E20180207-ts

    crumb n. 碎屑(尤指面包屑或糕饼屑); 面包心; 些许,少许; <俚>可鄙的人物;

  4. node.js在读取文件时中文乱码问题

    断更很久了........从今天开始会努力的持续更博,积极学习. 言归正传.今天在写node.js的demo时发现一个bug.我在node中读取本地的text文件时,发现英文的内容可以被读取,但是中文 ...

  5. Keras 文档阅读笔记(不定期更新)

    目录 Keras 文档阅读笔记(不定期更新) 模型 Sequential 模型方法 Model 类(函数式 API) 方法 层 关于 Keras 网络层 核心层 卷积层 池化层 循环层 融合层 高级激 ...

  6. NOI题库--盒子和小球系列 By cellur925

    题目传送门 盒子和小球之二:N个有差别的盒子(1<=N<=20).你有A个红球和B个蓝球.0 <= A <= 15, 0 <= B <= 15.球除了颜色没有任何区 ...

  7. NOIp 2010/Luogu P1525 关押罪犯 【二分图/并查集】 By cellur925

    题目传送门 感想:相信自己的想法!继续挖掘! 读完题目后:看到的最大值最小?二分答案啊!再仔细一看:wi达到了1e9,二分可能费点劲.(其实真的是可以的)而且check函数貌似并没有什么行之有效的写法 ...

  8. JAVA 毕业设计 辅导

    JAVA 毕业设计 辅导   =======================================================  

  9. Hdu 3488 Tour (KM 有向环覆盖)

    题目链接: Hdu 3488 Tour 题目描述: 有n个节点,m条有权单向路,要求用一个或者多个环覆盖所有的节点.每个节点只能出现在一个环中,每个环中至少有两个节点.问最小边权花费为多少? 解题思路 ...

  10. 【洛谷5398】[Ynoi2018]GOSICK(二次离线莫队)

    题目: 洛谷 5398 当我刚学莫队的时候,他们告诉我莫队能解决几乎所有区间问题: 现在,当我发现一个区间问题似乎难以用我所了解的莫队解决的时候,他们就把这题的正解叫做 XXX 莫队.--题记 (以上 ...