当前位置: 首页 > news >正文

manacher 马拉车算法 寻找最长回文子串

manacher 马拉车算法 寻找最长回文子串

例题

洛谷 P3805 【模板】manacher

image

回文串的定义

回文串是字符串中常见的一种,一个字符串是回文串代表这个字符串
从前往后和从后往前读是相等的,形式化定义就是一个长为 \(n\) 字符串
\(S\) 是回文的当且仅当对于任意 i,有 \(S_i = S_n−i+1\)

回文串的性质:一个回文串左右同时加一个字符,得到
的仍然是回文串。

启示
可以从一个中心开始向左右拓展,添加字符,能拓展就拓展,拓展不了那么说明以这个为中心的
更长的串一定也不是回文串。于是对于每一个中心点 \(c\),我们都存在一个最长回文半径 \(r\)
如图

image
中心点为a, 最长回文半径是3,绿色为可扩展字符,蓝色为不可扩展字符

奇偶串的处理

有些串的中心在两个字符中间,而有些串的中心正好是一个字符。为了方便起见,我们可以先在每个字符中间加入一个分割符,这样原串中所有的回文串就都以一个字符为中心了。
大概就是,假如我们现在有一个字符串 \(S = racecar\),我们就可以将
它变成一个字符串 \(S = |r|a|c|e|c|a|r|\)

答案统计

接下来只考虑以某个位置为中心的最长回文串半径 \(r_i\)(即最长回文串为 \(S[i − r_i + 1, i + r_i − 1]\)),原串的最长回文串长度就等于\(r_i − 1\)(因为中间加了分隔符),以该字符为中心的回文串有\(\llcorner r_i/2\lrcorner\)

算法原理

如果一个长回文串中有一个子回文串,那么这个子回文串翻转过后的位置一定也是一个回文串。
如图

image

记录当前最长的一个回文串(右端点最靠右),这样当我们寻找以当前字符 \(c\) 为中心的最长回文串时,我们可以直接用 \(c'\) 为中心的最长子回文串的半径为初始值\(c'\) 为当前字符 \(c\) 在最长回文串的对称点),然后在这基础上再进行拓展。需要注意的是,以 \(c\) 为中心的最长回文串实际上是 \(aeabcbaea\),是比长回文串更长的,所以我们需要把它缩减到长回文串内部再进行拓展,所以需要取一个 min。

如果当前中心已经不在最长回文串内了,那就直接从当前点 \(c\) (r为1) 开始拓展。

时间复杂度\(O(n)\)

代码

#include<bits/stdc++.h>
using namespace std;
char t[22000010];//加了分隔符的串 
int l[22000010];//以i为中心点的回文串的半径 
int main()
{string s;cin>>s;t[1]='|';//分隔符,避免区分奇偶串 int n=s.size();for(int i=1;i<=n;i++){t[2*i]=s[i-1];t[2*i+1]='|';}n=2*n+1;int c=0,r=-1;//c:最靠右的回文串的中心点,r:遍历过的串的最右右端点 int ans=0;//答案即最长回文串的长度 for(int i=1;i<=n;i++)//枚举中心点 {if(i<=r)//中心点在之前最右回文串的右端点之前,即可以通过之前的状态进行转移 {l[i]=min(l[2*c-i],r-i);//以i为中心点的半径是i关于c的对称点为中心点的回文串的半径和i与r距离的较小值 }else{l[i]=1;//扩展初始值为1 }while(i-l[i]>=1&&i+l[i]<=n&&t[i+l[i]]==t[i-l[i]])//子串被包含且构成回文,利用的是回文串的性质 {l[i]++;//半径加一 }if(i+l[i]-1>r)//中心点加半径大于遍历过的串的最右右端点{c=i;//更新中心点 r=i+l[i]-1;//更新最右右端点 } ans=max(ans,l[i]-1);//更新答案 }cout<<ans;return 0;
}

\({\cal {The }}\) \({\cal {end. }}\)

http://www.njgz.com.cn/news/510.html

相关文章:

  • 笛卡尔树
  • 如何获取集合控件中子项元素的容器
  • 火山引擎-大模型应用防火墙
  • chorme如何设置在新标签页打开页面?
  • Gentoo解决clocksource未使用tsc问题
  • UIUCTF 2024 syscalls
  • POLIR-Laws-民法典: 第三编 合同 : 第二分编 典型合同: 17.承揽
  • 2025-07-27 模拟赛总结
  • widedeep在adult数据集上的应用
  • POLIR-Laws-民法典: 第三编 合同 : 第二分编 典型合同
  • 协议版iM蓝号检测,批量筛选iMessages数据,无痕检测是否开启iMessage服务
  • 2025年7月27日
  • 连续动作强化学习中的反事实探索:揭示AI决策背后的可能性
  • ADC模数转换器
  • 启明星辰-大模型应用防火墙
  • VulnHub 靶场--broken(十六进制转图片)
  • TIM输入捕获
  • 文件权限标记机制在知识安全共享中的应用实践
  • PID
  • POLIR-Laws-民法典: 民法典 包括 并 废止 《合同法》
  • 18
  • 字节-大模型联邦精调方案
  • 分块
  • 并查集
  • 7-27
  • CVE-2021-21311 服务器端请求伪造(SSRF)漏洞 (复现)
  • 【Rag实用分享】小白也能看懂的文档解析和分割教程
  • 【纯干货】三张图深入分析京东开源Genie的8大亮点
  • JoyAgent综合测评报告
  • 【EF Core】为 DatabaseFacade 扩展“创建”与“删除”数据表功能