首页 > 编程语言 >算法随笔——manacher

算法随笔——manacher

时间:2024-05-04 11:11:43浏览次数:30  
标签:old int manacher 算法 str 随笔 回文

非常好学习资料

manacher

求最长回文子串

暴力

枚举回文中心 \([1,n]\),暴力向两边拓展,然后 \(checkmax\)。时间复杂度 \(O(n^2)\)
可以用二分哈希优化至 \(O(n \log n)\)

算法思路

当求解第 \(i\) 个字符为回文中心的时候,已经知道了 \([1,i-1]\) 之间的信息。
于是引入
\(p[i]\) :以 i 为中心的最长回文半径(即回文串的一半)
\(r\) :回文串右端点最远可以到达的位置,则该设回文串为 \([l,r]\)
\(m\) :\([l,r]\) 回文串的中心,\(m = (l + r)/2\),始终满足 \(m < i\)
\(k\) :i 关于 m 的对称点,$k = 2 * m -i $
image
image

因此 \(p[i] = min(r-i+1,p[2*m-i])\)

小tips

因为回文串有奇有偶,因此为了避免讨论,在每个字符之前和首尾插入一个 '#',可以保证每个回文串长度均是奇数,答案即为 \(max{p[i]} - 1\)。

char old[N],str[N];

int p[N],r,m;

int main()
{
	scanf("%s",old+1);
	int len = 0;
	//插入字符 初始化
	str[++len] = '#';
	for (int i = 1,l = strlen(old+1);i <= l;i++)
		str[++len] = old[i],str[++len] = '#';
	for (int i = 1;i <= len;i++)
	{
		if (i > r) p[i] = 1;
		else p[i] = min(p[2*m-i],r-i+1);
		while (i+p[i] <= len && i - p[i] >= 1 && 
		str[i+p[i]] == str[i-p[i]]) p[i]++; //暴力拓展
		//更新中心和最远右端点
		if (i + p[i] - 1 > r) r = i + p[i] - 1,m = i;
	}
	int ans = 0;
	for (int i = 1;i <= len;i++ ) ans = max(p[i],ans);
	cout << ans - 1 << endl;
	//答案等于(整条回文串-1)/2
	//即(p[i]*2-1 -1)/2 = p[i]-1
	return 0;
}

标签:old,int,manacher,算法,str,随笔,回文
From: https://www.cnblogs.com/codwarm/p/18172113

相关文章

  • A* 算法、PathFinding问题中的 allow diagonal 和 don't cross corners,以及 .map文件
    地址:https://webdocs.cs.ualberta.ca/~nathanst/papers/benchmarks.pdf关于地图文件:.map文件的格式参考:https://movingai.com/benchmarks/formats.html......
  • [随笔] 快速幂
    没办法老师让预习,我就只能把我快一年前的快速幂翻出来不放洛谷了,老师容易窥探>﹏< 老师の问题1.快速幂的原理是什么每一步都把指数分成两半,而相应的底数做平方运算2.如果求2的23次方,快速幂的具体过程是什么∵23=2^0+2^1+2^2+2^4∴2^23=2^2^0*2^2^1*2^2^2*2^2^4 位......
  • Kosaraju 算法
    引入Kosaraju算法用于求解强连通分量,在稠密图下复杂度会比tarjan算法要优秀。(?过程对整个图进行搜索,并且将没一个顶点按照DFS序压入栈中。建一个反图。对于栈中的每一个点再反图上跑一遍DFS,现在跑出来的子图即为一个强连通分量。标记这几个点。重复执行操作......
  • m基于LDPC编译码的matlab误码率仿真,对比SP,MS,NMS以及OMS四种译码算法
    1.算法仿真效果matlab2022a仿真结果如下:    2.算法涉及理论知识概要       低密度奇偶校验码(LDPC)译码是现代通信系统中一种高效的错误校正技术,广泛应用于无线通信、卫星通信和数据存储等领域。LDPC码因其良好的纠错性能和接近香农极限的潜力而受到重视。本文......
  • 算法基础课笔记
    二分整数二分有单调性一定可以二分,二分不一定有单调性数的范围intmain(){scanf("%d%d",&n,&m);for(inti=0;i<n;i++)scanf("%d",&q[i]);while(m--){intx;scanf("%d",&x);intl......
  • 代码随想录算法训练营第10天 | 栈和队列 232.用栈实现队列 225.用队列实现栈
    leetcode232.用栈实现队列题目232.用栈实现队列请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):实现MyQueue类:voidpush(intx)将元素x推到队列的末尾intpop()从队列的开头移除并返回元素intpeek()返回队列开头的......
  • raft算法和etcd代码解析-5.应用模块的启动
    Node接口Node是raft应用模块在节点上的抽象,也是应用模块和算法模块交互的入口应用模块持有Node作为算法模块的引用,通过调用Node接口的API与算法模块通信,通信方式是通过若干个Channel异步完成的。//Noderepresentsanodeinaraftcluster.typeNodeinterface{ //告知......
  • 读天才与算法:人脑与AI的数学思维笔记16_音乐图灵测试
    1.      艾米1.1.        人工智能作曲家1.1.1.          分析机可能会生成任意复杂程度、精细程度的科学的音乐作品1.1.1.1.           阿达·洛夫莱斯1.1.2.          巴赫的作品是大多数作曲家开始学习创作的起点,也是......
  • 随机森林Adaboosting算法与Python实现(二)
    AdaBoost是Freund和Schapire于1996年提出的一种集成学习方法。它的核心思想是通过迭代训练一系列弱分类器,每次调整样本权重以便更好地拟合被前一轮分类器错误分类的样本,从而构建一个强分类器。最终的模型是基于这些弱分类器的加权组合。AdaBoost广泛应用于二分类和多分类问题,尤其......
  • leetcode算法热题--最长连续序列
    题目给定一个未排序的整数数组nums,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。请你设计并实现时间复杂度为O(n)的算法解决此问题。示例1:输入:nums=[100,4,200,1,3,2]输出:4解释:最长数字连续序列是[1,2,3,4]。它的长度为4。示例2:输入:nums=......