首页 > 其他分享 >重谈 manacher

重谈 manacher

时间:2024-09-25 11:36:35浏览次数:5  
标签:int manacher texttt pos mid 重谈 mr 回文

  • 名称:马拉车,即 manacher。

  • 实现问题方面:处理出整字符串 \(s\) 的回文串个数、位置。

  • 中心数组:数组 \(p\),\(p_i\) 表示以第 \(i\) 个字符为中心最长回文半径。

  • 预处理:将字符串间加入特殊字符(一般是 $),以及结尾和开头的特殊处理。

  • 优势:马拉车的时空复杂度和字符集的大小无关,为 \(O(n)\)。

实现

马拉车最核心的思想就是利用前面的信息得到后面的信息。

最重要的变量:\(\texttt{mr,mid}\)

\(\texttt{mr}\) 表示扩展到最远的回文半径,\(\texttt{mid}\) 表示最远回文半径的中心。

如果一个点的位置 \(pos\) 满足 \(pos\in[mid,mr]\),我们可以预处理出这个点的答案:\(\min(p[2\times mid -pos],mr-i+1)\)。这是由对称得到的,也就是说利用 \(i\) 与 \(mid\) 对称的点的答案,不难看出在 \(mr-i+1\) 范围内一定是合法的。否则我们暴力扩展,容易发现,每暴力扩展一次,\(mr\) 同时也一定会扩展一次。根据 \(mr\) 是一直递增的,容易分析出时间复杂度为 \(O(n)\)。

  • 代码:
#include<bits/stdc++.h>
#define N 22000005
using namespace std;
int n,cnt;
char t[N],s[N];
void build()
{
	n=strlen(t+1);
	s[0]='>',s[1]='#';
	for(int i=1;i<=n;i++)
		s[i<<1]=t[i],s[(i<<1)|1]='#';
	n=(n<<1)|1;
}
int ans;
int mr,mid;
int p[N];
void solve()
{
	for(int i=1;i<=n;i++)
	{
		if(i<=mr) p[i]=min(p[mid*2-i],mr-i+1);
		while(s[i-p[i]]==s[i+p[i]]) p[i]++;
		if(i+p[i]>mr) mr=i+p[i]-1,mid=i;
		ans=max(ans,p[i]-1);
	}
}
int main()
{
	scanf("%s",t+1);
	build();
	solve();
	printf("%d",ans);
	return 0;
}

只有彻底明白一个算法,才不会在考场上后悔。

标签:int,manacher,texttt,pos,mid,重谈,mr,回文
From: https://www.cnblogs.com/g1ove/p/18430989

相关文章

  • Manacher 马拉车
    Manacher马拉车,一种为了求字符串中最长的回文字串的算法。这个算法是从暴力的方法转化过来的,暴力肯定是枚举字符串每个字符作为中心,然后向外扩展,这样的复杂度为\(O(n^2)\)。而Manacher则是按照回文对称的性质的进行优化的,首先回文串有奇数串\(aba\)和偶数串\(abba\)如果......
  • Manacher 算法
    引入:万恶的字符串问题你是否看到字符串就感到迷茫而无所适从?你是否看到“border”“回文”等字眼就感到大脑宕机只会暴力?如果你像我一样有这种症状,不妨一起来学习一下Manacher算法。当你掌握了Manacher之后,你会发现,很多字符串问题都变成了板子,而你再也不用担心因为字符串抱......
  • Manacher 算法
    算法介绍\(\text{Manacher}\)算法(又名马拉车),是一种常用于处理回文字符串的算法。其代码量很小,却可以在\(O(n)\)的时间复杂度内处理问题算法思想和其他大多数算法一样,\(\text{Manacher}\)算法利用现有的信息获得下一部分的信息。经典例题:给定一个字符串\(s\)。求出其最长......
  • 算法·理论:Manacher 笔记
    \(\text{Manacher}\)来啦!\(\text{Manacher}\)并没有什么前置知识,比\(\text{KMP}\)简单多了。前置处理\(\text{Manacher}\)算法用于解决回文串相关问题,先看几个基本概念:回文中心、回文半径,这些看字面意思就能猜到。还有一个重要问题:对于回文串,有长度为奇数或长度为偶数之......
  • Manacher
    马拉车的用处是求出一个字符串以每个位置为回文中心的最大回文半径。负面效果是会让字符串每两个字符中间插入一个间隔符,增加代码难度。马拉车的思想是尽量利用之前求出的信息,用以前的回文推出后面的回文。当前回文中心如果在以前求出的回文范围内,那当前回文中心可以对称到一个......
  • manacher
    manacher用途:找字符串中的最长的回文子串。考虑该问题【模板】manacher求最长回文串长度。该如何做?暴力\(O(n^2)\)就是枚举回文中心,向外拓展。代码太简单了,就不挂了。其实是懒得打二分+hash\(O(n\logn)\)将字符串正向hash,反向hash,枚举回文中心,二分答案即可......
  • 回文结构 manacher & PAM 马拉车 & 回文树
    manacher马拉车通过在每个字符间插入一个特殊字符,使得字符串长度为奇数,从而保证每个字符都有中心。在每个中心记录回文串的长度。马拉车的扩展方式和\(Z\)函数类似。都是通过映射之前已经算过的位置,然后尽可能的向右扩展。复杂度\(O(n)\)通常马拉车的题目统计回文串需要与其他......
  • P3805 【模板】manacher
    原题链接题解细节所有字符的回文半径初始化为1rmax=1ans=1code#include<bits/stdc++.h>#definelllonglongusingnamespacestd;voidsolve(){strings;cin>>s;strings1;for(inti=0;s[i];i++){s1+='#';s1+=......
  • 题解:CodeForces 835 D Palindromic characteristics[区间dp/马拉车Manacher]
    CodeForces835DD.Palindromiccharacteristicstimelimitpertest:3secondsmemorylimitpertest:256megabytes*inputstandardinputoutputstandardoutputPalindromiccharacteristicsofstring\(s\)withlength\(|s|\)isasequenceof\(|s|\)in......
  • 「字符串」Manacher算法(马拉车)/ LeetCode 05(C++)
    给你一个字符串 s,找到 s 中最长的回文子串。示例1:输入:s="babad"输出:"bab"解释:"aba"同样是符合题意的答案。示例2:输入:s="cbbd"输出:"bb"思路我们回想中心扩散法:某字符处的中心扩散完毕后,其实已经将它身前身后的字符段落都搜索过了,那么如果我们搜索其后的字......