Manacher入门

写在前面

manachermanachermanacher比想象中好理解得多

至少它给了我学习字符串的信心

能干啥

manachermanachermanacher,中文马拉车(您别说,这名字还挺形象),主要用于计算字符串每一个位置为对称中心的回文串长度(等价于个数)

包括偶回文,即长度为偶数的回文串

算法流程

考虑下面的问题:给一个字符串,求最长回文子串

我会暴力!

枚举判断O(n3)O(n^3)O(n3)

我会优化!

考虑到以ccc为中心,acbacbacb不是回文串,左右怎么接都不是回文串

所以可以枚举中间点(偶回文判断一下即可),然后向两边拓展

复杂度O(n2)O(n^2)O(n2)

我会玄学!

O(n2)O(n^2)O(n2)还不够 不符合字符串算法均为线性复杂度公理

在此基础上继续优化

我们记录maxrmaxrmaxr为目前找到的回文串右端点的最右的位置 pospospos为这个回文串的对称中心

开一个数组pip_ipi表示回文半径(和其他文章不同,本文回文半径指一个端点到中心的距离,即直接相减)

回文串最本质的特征是什么?左右关于中心对称。

如果一个回文串对称中心的一侧有另一个回文子串,那么对称过去也有一个相同长度的回文子串

在这里插入图片描述
黄色部分完全一致,这就是manacher的核心

(先不考虑偶回文)

i&lt;maxri&lt;maxri<maxr(取不取等于无所谓)

j,ij,ij,i关于pospospos对称 即j=pos∗2−ij=pos*2-ij=pos2i

根据上面的推导,令pi=pjp_i=p_jpi=pj即可

当然如果jjj为中心的最长回文左端点越界了
在这里插入图片描述
那就不能保证上面的性质(实际上可以保证不成立),所以要和j−maxlj-maxljmaxl(即maxr−imaxr-imaxri)取minminmin

jjj越界时还需要让iii继续拓展。当然为了刷短代码减少讨论,都拓展一下好了

i≥maxri \geq maxrimaxr

在这里插入图片描述
啥都不能保证,直接暴力扩展

综上:

  1. 如果i&lt;maxri&lt;maxri<maxr,按上述条件更新pip_ipi
  2. 暴力拓展
  3. 更新maxrmaxrmaxrpospospos

然后……对,没了,就三行。

这就是manachermanachermanacher的全过程,复杂度O(n)O(n)O(n),后面有证明

实现

上面没有讨论偶回文,主要是转化过程比较难看,容易使人丧失信心。

其实也不难。只需要在字符两两之间加一个字符,如‘#’;然后首尾也加上‘#’,再在开头加一个标识符防止越界。注意要和之前的不同,如‘@’

这样偶回文可以看做中心是‘#’的回文

普及T1模拟水平

这样处理后,所有回文串左右端点都是‘#’,然后就可以跑了

证明

什么?不是只改了一个地方吗?怎么变O(n)O(n)O(n)了?

回顾整个流程,真正暴力拓展的时候要么jjj左端点越界,要么iii越界(jjj左端点没越界时,根据反证法,iii实际上无法拓展)

jjj左端点越界时,iii右端点出生点就在maxrmaxrmaxr,再拓展就超出去了

也就是说,每次暴力拓展,都意味着maxrmaxrmaxr更新,而maxrmaxrmaxr只会往右跑

换一个角度,实际上暴力拓展是把maxrmaxrmaxr推到最右边,次数是O(n)O(n)O(n)

所以总复杂度是O(n)O(n)O(n)

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#define MAXN 1000005
using namespace std;
char s[MAXN],ss[MAXN];
int pos,maxr;
int p[MAXN];
int main()
{scanf("%s",s+1);int n=strlen(s+1);for (int i=1;i<=n;i++) ss[i<<1]=s[i],ss[(i<<1)|1]='#';n=(n<<1)|1,ss[0]='@',ss[1]='#';strcpy(s,ss);for (int i=1;i<=n;i++){if (i<maxr)	p[i]=min(p[(pos<<1)-i],maxr-i);while (s[i-p[i]-1]==s[i+p[i]+1]) ++p[i];if (i+p[i]>maxr) maxr=i+p[i],pos=i;}return 0;
}

由于所有位置为中心的最长回文串左右端点都是‘#’

回文串长度leni=2pi+1−12=pilen_i= \frac {2p_i+1-1}{2} = p_ileni=22pi+11=pi

然后用来搞事情就可以了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/315304.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HDU.6761.Minimum Index(Lyndon分解)

题目大意&#xff1a;给一个字符串&#xff0c;求字符串的所有前缀的最小后缀&#xff1b; 思路&#xff1a;主要还是要理解Lyndon串的算法的整一个过程 参考&#xff1a;搬运来自 #include <iostream> #include <cstdio> #include <fstream> #include <…

C#规范整理·异常与自定义异常

这里会列举在C#中处理CLR异常方面的规范&#xff0c;帮助大家构建和开发一个运行良好和可靠的应用系统。前言迄今为止&#xff0c;CLR异常机制让人关注最多的一点就是“效率”问题。其实&#xff0c;这里存在认识上的误区&#xff0c;因为正常控制流程下的代码运行并不会出现问…

Codeforces Round #619 (Div. 2) D. Time to Run 矩阵回路构造

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个n∗mn*mn∗m的矩阵&#xff0c;每两个相邻点之间有个双向边&#xff0c;问你能不能走满kkk步&#xff0c;每一步走的边不同&#xff0c;但是点可以相同&#xff0c;换句话说就是走的边不能再走了。输…

HDU - 6756 Finding a MEX-分块思想

https://vjudge.net/problem/HDU-6756 题目大意&#xff1a;给你一个无向图&#xff0c;每个点有权值a&#xff0c;将f&#xff08;u&#xff09;定义为对u的邻居的集合求mex&#xff1b; 有两个操作&#xff1a; 1&#xff1a;将u的权值修改为x 2&#xff1a;查询f&#x…

中高级数论 [欧拉函数线性筛,二次剩余]

欧拉函数线性筛 对于素数ppp, φ(p∗i){p−1i1p∗φ(i)p∣i(p−1)∗φ(i)p∤i\varphi (p*i) \begin{cases} p-1& i1\\ p*\varphi(i)& p \mid i\\ (p-1)*\varphi(i) & p \nmid i \end{cases}φ(p∗i)⎩⎪⎨⎪⎧​p−1p∗φ(i)(p−1)∗φ(i)​i1p∣ip∤i​ 证明&am…

C#中await/async闲说

自从C#5.0增加异步编程之后&#xff0c;异步编程越来越简单&#xff0c;async和await用的地方越来越多&#xff0c;越来越好用&#xff0c;只要用异步的地方都是一连串的异步&#xff0c;如果想要异步编程的时候&#xff0c;需要从底层开始编写&#xff0c;这样后边使用的时候就…

Codeforces Round #619 (Div. 2) E. Nanosoft 思维 + 二维前缀和

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 考虑到最大面积是由四种颜色构成的&#xff0c;且四种颜色可以从中心扩展出去&#xff0c;所以我们分别维护四种颜色的二维前缀和&#xff0c;O(1)O(1)O(1)计算矩阵内颜色的个数。现在我们…

CF 613D - Kindom and its Cities-虚树

https://codeforces.com/problemset/problem/613/D 题目大意&#xff1a;有n个点&#xff0c;每次询问要最少移除多少个点使得关键点分隔 思路&#xff1a;首先&#xff0c;如果关键点是相连的话&#xff0c;那么一定是不行的。 然后因为询问的总节点数不多&#xff0c;可以…

FFT:从入门到沉迷

终于学会了FFTFFTFFT并无法自拔 啥是FFT FFTFFTFFT指快速傅里叶变换 在OIOIOI中的应用是O(nlogn)O(nlogn)O(nlogn)计算函数卷积 人话&#xff1a;多项式乘法 多项式毒瘤模板题的万恶之源 系数表达式与点值表达式 系数表达式就是平常的表示方法 f(x)∑i0naixif(x)\sum_{i0…

HDU - 6769-In Search of Gold-二分+树形dp

https://vjudge.net/problem/HDU-6769 题目大意&#xff1a;给你n个点&#xff0c;有n-1条边&#xff0c;每条边有a&#xff0c;b两个权值&#xff0c;给你一个k&#xff0c;恰好有k条边的权值取a&#xff0c;其余取b的时候&#xff0c;树的直径的最小值。 思路&#xff1a;答…

Codeforces Round #701 (Div. 2) E. Move and Swap 思维 + dp

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 由于是按层来的&#xff0c;所以我们肯定先按照层来分组。 定义dp[i]dp[i]dp[i]为红棋在位置iii的时候的最大得分和。 先考虑不换的情况&#xff0c;我们对于每个点都从他的父节点转移过来…

用 docker-compose 启动 WebApi 和 SQL Server

本系列文章所要做出的演示架构基于 .NET Core Web Api、MSSQL、Skywalking 和 nginx &#xff0c;这些都会通过docker-compose一键创建/启动容器&#xff0c;然后用 Azure DevOps 发布上线。所以本系列文章重点并不是如何写好.NET Core&#xff0c;而是围绕着 .NET Core 的容器…

OI群论:从入门到自闭

怎么这么多阅读啊…… 这篇文章是群论&#xff08;其实只有Polya&#xff09;在信息学奥赛中计数的运用&#xff0c;并不是群论的讲义…… 群论可以说是数学中最高深的内容&#xff0c;一个oier去深入了解是不现实的。因此&#xff0c;我们只需要知道结论。 本文主要讲解群论…

2020牛客暑期多校训练营(第二场)Just Shuffle

https://ac.nowcoder.com/acm/contest/5667/J 题目大意&#xff1a;给你一个置换A&#xff0c;使得置换P^kA,让你求出置换P。 思路&#xff1a;我们根据置换A再置换z次&#xff0c;那么就等于置换p 置换z*k次,如果z*k%len0&#xff0c;那么将会回到单位序列&#xff0c;那我们…

Codeforces Round #619 (Div. 2) F. Super Jaber 多源bfs + 思维转换

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个矩阵&#xff0c;每个格子都有一个颜色kkk&#xff0c;每秒可以移动到相邻矩阵或者瞬移到同一颜色的任意矩阵。有qqq个询问&#xff0c;每次询问给出两个点&#xff0c;求从一个点到另一个点的最短时…

你可以保持沉默,但你所说的一切都将成为呈堂证供——浅谈Azure WORM保护

本文作者|Yuan Han本文来源|Reid爸的菜园子美国安然事件后&#xff0c;电子数据的合规性保存越来越受到重视&#xff1b;各国政府制定了一系列的法律&#xff0c;如美国《赛班斯法案》等&#xff0c;对于不同类型的电子数据保留期限做了严格规定&#xff1b;国内也没落后&#…

后缀自动机:从入门到放弃

写在前面 后缀自动机&#xff0c;简称SAMSAMSAM,是一种十分优秀的字符串匹(shu)配(ju)算(jie)法(gou) 字符串界的bossbossboss&#xff0c;几乎可以解决全部正常的字符串题目 至少我前前后后学了一年&#xff0c;听过444次课&#xff0c;几度怀疑自己不适合oioioi 请做好心…

2021牛客第一场 K.Knowledge Test about Match

https://ac.nowcoder.com/acm/contest/11166/K 题意就是使得图中的那个式子最小&#xff0c;你的答案不一定是要最标准的&#xff0c;只要平均水平下和标准值的偏差不超过4%就行了。 有了这个提示&#xff0c;那我们直接贪心瞎搞就行了&#xff0c;只有符合换过去的收益的增大…

Codeforces Round #620 (Div. 2) F2. Animal Observation (hard version) dp + 线段树

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 比如下面这个图&#xff1a; 思路&#xff1a; 对于这个题&#xff0c;比较容易就能考虑到dpdpdp&#xff0c;设f[i][j]f[i][j]f[i][j]为到了第iii行&#xff0c;覆盖了[j,jk−1][j,jk-1][j,jk−1]范围时候…

设计模式之总体介绍

1. 背景与介绍设计模式是经过反复使用、经过分类的代码总结。设计模式的目的是提高代码可重用性和可靠性&#xff0c;并使代码条理清晰、易于理解、易于维护。设计模式描述了在各种情况下&#xff0c;要选择什么样的方案来解决问题。设计模式通常以类和对象来描述其中的关系和相…