<学习笔记>manacher算法

manacher 算法详解 manacher 算法 阅读详情

我是吐槽,你看不到我~~ (*/ω\*) 清北学堂学习第七天来了个特别漂亮的小姐姐(syq)讲了字符串算法,如 kmp,manacher,hash…还特别安利说manacher可以O(n)复杂度解决回文子串问题233 上课只顾着看小姐姐了。下午考试她说有上午学的一部分内容,说帮我们巩固一下。道理我都懂,可是上来第一题就是manacher算法是要闹那样啊,内流满面T^T。。。我上午只看了看思想啊QAQ。。。一定要把模板保存下来。。。

回文串问题

最长回文子串问题:给定一个字符串,求它的最长回文子串长度(n<=10^7)

*回文串:正序和逆序相等的串。从中心轴出发左右对称,中心轴可以是一个字符,也可以是两个字符间的一个间隙。

暴力吗?
枚举每个子串暴力判断…n^3 !!
那优化一下?
枚举中心轴看最长扩展长度。
那字符间隙呢?
在字符间隙里再插上一个#就好了… n^2!(保证#在原串中没有出现过)
还能优化吗?
发现形如 ababababa 发现枚举第3个b时的回文串在枚举第三个a时已经被匹配过一遍了,考虑能不能像kmp算法一样利用之前的匹配信息?

答案是可以的!

Manacher算法

在O(n)时间内,计算出一个字符串以每个位置为中心轴(一个字符或者字符间隙)最长能扩展出多长的回文串。

预处理:将所有的字符都转为奇数长度。
aba–> #a#b#a#
abba–>#a#b#b#a#

另,设r[i]为以i为中心轴的最长匹配半径(不包括i)

栗子:

# a # b # a #
0 1 0 3 0 1 0
# a # b # b # a #
0 1 0 1 4 1 0 1 0

发现r[i]恰好就是以i为中心的最长回文串长度。

能否快速求出r?

定义两个变量:

pos=一个当前向右延伸的位置最远的回文串的中心轴。
maxn_r=这个中心轴的r。

这里写图片描述

前提:i>pos

计算r[i]时分三种情况讨论:

① i < maxn_r 时: 取i关于pos的对称点j
由回文串性质,可知
⑴ 若r[j]+i<=maxn_r , r[i]=r[j];

这里写图片描述

⑵若r[j]+i>maxn_r,
可知 i~maxn_r一段一定是回文串。
从maxn_r+1开始逐位匹配并更新maxn _r和pos。
maxn_r=i+r[i],pos=i;

这里写图片描述

② i>=maxn_r时 从i往右开始逐位匹配,maxn _r=i+r[i],pos=i;

这里写图片描述

代码:

void Manacher()
{
    l=strlen(b);
    for(int i=0;i<l;++i)
    {
        a[i<<1]='#';
        a[i<<1|1]=b[i];
    }
    l=l*2+1;
    a[l-1]='#';
    maxn_r=0,pos=0;
    for(int i=0;i<l;++i)
    {
        if(maxn_r>i) r[i]=min(maxn_r-i,r[2*pos-i]);
        else r[i]=0;
        while(i+r[i]+1<l&&i-r[i]-1>=0&&a[i+r[i]+1]==a[i-r[i]-1]) r[i]++;
        if(r[i]+i>maxn_r)
         {
            maxn_r=r[i]+i;
            pos=i;
         }
    }
}

一道简单题

题目描述

小 A 是个学渣,很快就要到 3000 年 NOIprofessional 初赛了,然而他什么题都不会写。
于是他开始研究往年卷的选项分布(然并卵)。
小 A 有 M 份试题。 由于是 professional 版本的考试,初赛试题题目数量 N 非常大。 小
A 发现,某些年份的答案序列里有很多长度超过 k 的回文子串。 极长回文子串 str 定义
为以答案序列 s 中不存在与 str 同对称轴的更长回文子串。 小 A 想知道,每个年份的答
案序列里有多少长度超过 k 的极长回文子串。

输入格式

第一行两个数字 M,k,表示试卷数和长度下限 k
接下来 M 行,每行一个正整数和一个字符串,表示试题的年份和答案,答案序列不区
分大小写。

输出格式

输出共 M 行,每行两个数,第一个数为年份,第二个数为长度超过 k 的极长回文子串
的数量。按照数量递减,数量相同时年份递增的顺序输出。

样例输入

5 3
2011 bacddcb
2000 cacac
2012 aaacdadd
2008 dcdaa
1999 abcda

样例输出

2000 3
2012 2
2008 1
2011 1
1999 0

格式要求

输入文件 Xuezha.in
输出文件 Xuezha.out
时间限制:1s 内存限制:256MB
数据范围
年份 Y,2000<=Y<3000
对于 30%的数据,1<=M<=10,1<=N<=100,1<=k<=100
对于 100%的数据,1<=M<=100,1<=k<=100000,1<=N<=100000

模板题呦φ(>ω<*)

特别注意!!!题目里是不区分大小写的!!!就是说数据里有大写!!就这一点全场wa了一片,没几个有分的QAQ。 wa的一声就哭了。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

int maxn_r,pos,l,k,K,M;
int r[200050];
char a[200050],b[100050];
struct maple{
    int year;
    long long num;
}Paper[120];
bool cmp(maple a,maple b)
{
    if(a.num==b.num) return a.year<b.year;
    else return a.num>b.num;
}
void Done()
{
    l=strlen(b);
    for(int i=0;i<l;++i)
    {
        a[i<<1]='#';
        if(b[i]>='A'&&b[i]<='Z') a[i<<1|1]=b[i]-'A'+'a';  // 单独写会T , mengbi
        else a[i<<1|1]=b[i];
    }
    l=l*2+1;
    a[l-1]='#';
    maxn_r=0,pos=0;
    for(int i=0;i<l;++i)
    {
        if(maxn_r>i) r[i]=min(maxn_r-i,r[2*pos-i]);
        else r[i]=0;
        while(i+r[i]+1<l&&i-r[i]-1>=0&&a[i+r[i]+1]==a[i-r[i]-1]) r[i]++;
        if(r[i]+i>maxn_r)
         {
            maxn_r=r[i]+i;
            pos=i;
         }
    }
}

int main()
{
    freopen("Xuezha.in","r",stdin);
    freopen("Xuezha.out","w",stdout);
    scanf("%d%d",&M,&K);
    for(int i=1;i<=M;++i)
    {
        scanf("%d",&Paper[i].year);
        Paper[i].num=0;
        scanf("%s",b);  // 这里用cin,cout也会T
        Done();
        for(int j=0;j<l;++j)
           if(r[j]>=K) ++Paper[i].num;
    }
    sort(Paper+1,Paper+M+1,cmp);
    for(int i=1;i<=M;++i)
    {
        printf("%d %lld\n",Paper[i].year,Paper[i].num);
    }
    return 0;
}
求回文子串_O(n)_manacher算法 求回文比较好的一种算法,很值得了解与学习 立即下载

相关推荐

Manacher算法:求解最长回文字符串,时间复杂度为O(N)

Manacher算法:求解最长回文字符串,时间复杂度为O(N) 回文串定义:“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。回文子串,顾名思义,即字符串中满足回文性质的子串。

Manacher (马拉车算法)

Manacher (马拉车算法) 的介绍 中心扩展算法 —— 优化 —— 马拉车 P3805 模板manacher 算法 P1659 [国家集训队]拉拉队排练 P4555 [国家集训队]最长双回文串

日常记录,挨打要立正! 2万+

ConvLSTM时空预测实战代码详解

ConvLSTM代码复现

JaysonWong的博客 1万+

Manacher算法(马拉车算法)

Manacher算法,又叫“马拉车”算法,可以在时间复杂度为O(n)的情况下求解一个字符串的最长回文子串长度的问题。

诸君拔剑吧. 4280

Python xlwings报错解决:从‘NoneType‘到完美运行WPS表格的完整指南

本文深入解析了使用Python xlwings库自动化WPS表格时遇到的经典'NoneType'报错(AttributeError: 'NoneType' object has no attribute 'apps')的根源与解决方案。核心在于pywin32版本与WPS的兼容性问题,文章提供了从版本降级、依赖管理到构建健壮自动化环境的完整实战指南,帮助开发者彻底解决兼容性难题,实现稳定运行。

n4o5p6q7r的博客 303

Android Termux 安装Kali Linux 或 kali Nethunter史诗级详细教程

Termux 安装kali

风云小虾米的博客 6万+

Manacher算法

Manacher 算法用于求解字符串中最长回文子串的问题。

Psychosocial的博客 4304

QGIS v3.28 高效加载OSM在线地图的三种实用方法

本文详细介绍了在QGIS v3.28中高效加载OSM在线地图的三种实用方法:通过XYZ Tiles直接连接、使用QuickMapServices插件以及配置WMS/WTMS服务。针对每种方法提供了具体操作步骤、常见问题解决方案和性能优化建议,帮助用户根据需求选择最适合的方案,提升GIS工作效率。

weixin_29233333的博客 433

【通俗易懂搞算法】一篇文章弄懂Manacher算法

本文主要讲解manacher算法,将其思路、优化方法、代码实现都通过图形、文字进行讲解,保证文章的通俗易懂。

懒洋洋的博客 2414

SAR图像降噪:基于小波变换和双边滤波器的Matlab实现

小波变换和双边滤波器是常用的图像降噪技术,它们可以在保持图像细节的同时有效抑制噪声。本文介绍了基于小波变换和双边滤波器的SAR图像降噪方法,并提供了相应的Matlab源代码。通过对比原始图像和降噪后的图像,可以观察到噪声得到一定程度的抑制,同时保留了图像的细节信息。本文将介绍一种基于小波变换和双边滤波器的方法,用于SAR图像的降噪,并提供相应的Matlab源代码。希望这篇文章能够帮助您理解基于小波变换和双边滤波器的SAR图像降噪方法,并为您提供实现该方法的Matlab源代码。对图像的高频部分进行降噪处理。

ScriptCharm的博客 839

R语言做一个 GM (1,1)灰色预测模型

累加生成是GM(1,1)模型的另一个重要步骤,它通过构造累加生成序列,把非线性非平稳时间序列转化为线性平稳时间序列。GM(1,1)是一种基于灰色系统理论的预测模型,通常用于中小样本的非线性、非平稳时间序列数据分析。灰色预测模型的核心是灰度处理,将原始时间序列转化为灰色时间序列。这里使用R语言中的diff函数对时间序列进行一次差分,然后对结果取累加和得到灰度序列。以上是GM(1,1)灰色预测模型在R语言中的实现步骤。需要注意的是,GM(1,1)模型适用于中小样本的时间序列预测,对于长期预测效果可能较差。

Mrrunsen的博客 3841

Manacher算法的图示理解和代码实现

文章目录Manacher算法的图示理解和代码实现需要解决的问题第一种:暴力解法第二种:Manacher算法求解Manacher算法中的三个概念:Manacher算法中分四种情况讨论Manacher算法的代码实现Manacher算法的应用 Manacher算法的图示理解和代码实现 需要解决的问题 寻找一个字符串中最长的回文子串。 第一种:暴力解法 思想:以i为起点,向两边扩展,寻找以i为中心的最长回文子串。 复杂度:O(n2) 补充:回文的形式有奇数回文和偶数回文,比如1221是偶数回文,12321是奇数回文

何时立秋的博客--向前有路,未来可期 1804

实现两端固支梁热力耦合的有限元分析

在本文中,我们将使用Matlab实现两端固支梁的热力耦合有限元分析。我们假设梁的材料是均匀的,梁的截面积为1,长度为1,两端固支,且受到均匀分布的热荷载。接下来,我们需要组装全局刚度矩阵和热传导矩阵。对于两个相邻的元素,它们共享一个节点,因此需要使用连接矩阵将局部矩阵组装成全局矩阵。接下来,我们需要定义元素刚度矩阵和热传导矩阵。然后,我们需要定义载荷向量。然后,我们需要定义边界条件。在这个例子中,梁的两端固支,因此我们需要将两端节点的位移限制为0。最后,我们需要解决线性方程组,得到节点的位移和温度分布。

CyberSparkZ的博客 396

算法学习->manacher( 最长回文串的长度 )

一、关于manacher算法 马拉车算法,用于求出一个字符串中最长的回文串长度。 二、算法实现思路 三、模板 int p[maxn&amp;lt;&amp;lt;1]; char snew[maxn&amp;lt;&amp;lt;1],s[maxn]; int init(){ int len = strlen(s),cnt = 0; snew[0] = '$'; for(int i = 0;i &amp;...

wuyileiju__的博客 264

基于混合智能框架的景区边界范围预测与补全系统

摘要 本文提出一种混合智能框架,结合随机森林模型和GIS规则约束,解决景区边界缺失问题。系统基于Python和ArcGIS平台,利用多源地理空间数据训练随机森林分类器预测景区范围,并集成地形、水文、道路等GIS规则进行优化。实验结果表明,该方法能有效预测15000个景区的边界,精度优于单一模型。创新点在于: 1)数据驱动与知识驱动相结合的混合智能范式; 2)面向全国尺度的大规模边界补全; 3)提供完整的Python+ArcGIS实现方案。该系统为景区精细化管理提供了技术支撑,具有实用价值。

huanghm88的专栏 281

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

React Native跨平台技术基于HarmonyOS API 24在开源鸿蒙中查找最长回文子串的算法,使用中心扩展法(Center Expansion Algorithm)来实现这个功能

在React Native中开发一个组件来查找最长回文子串,你可以遵循以下步骤。这个过程涉及到编写一个React Native组件,并在其中实现最长回文子串的算法。这里,我们将使用中心扩展法(Center Expansion Algorithm)来实现这个功能。步骤 1: 创建React Native项目步骤 2: 创建组件在项目中创建一个新的组件,例如。步骤 3: 在App中使用组件在App.js步骤 4: 运行应用TextInputButtonText。

wanmeijuhao的博客 154

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

最长回文子串------Manacher算法

文中主要讲述Manacher算法求解最长回文子串问题,包括Manacher算法基本思想、manacher算法对称性中的计算、manacher算法代码实现、最长回文子串长度及所有的最长回文子串和个数(数量)。

Python基础详解教程,让编程变得简单! 2370

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

算法学习之Manacher算法

情况二,i 的对称点 i'在 中心点回文子串内部,此时可以直接快速获取最长回文半径,应该返回 'i''的回文半径(即pr[2 * C - i]), 这种情况下 pr[2 * C - i] 一定小于 R - i + 1的,有疑问的可以回去上面的案例看。当前下标为i的字符取到的最远右端距离=i+回文半径数组[i]−1当前下标为i的字符取到的最远右端距离 = i + 回文半径数组[i] - 1当前下标为i的字符取到的最远右端距离=i+回文半径数组[i]−1。经过一轮的遍历最终可以获得最大的回文子串长度。

BASK2312的博客 384

Manacher算法详解

文章目录1 算法背景2 常规求解3 Manacher算法3.1 字符串预处理3.2 回文半径数组3.3 对称关系3.4 填充数组3.5 算法流程以及伪代码3.6 实例4 结束 1 算法背景   Manacher算法用于解决最长回文子串问题。给定字符串sss,求其最长回文子串,回文子串形如abaabaaba、abbaabbaabba。例如: s = "abcbbc" 回文子串有:"bcb"、"cbb...

qq_39378221的博客 1012

manacher算法详解(马拉车算法)

马拉车算法 Manacher算法是由题目“求字符串中最长回文子串的长度”而来。比如 abcdcb 的最长回文子串为 bcdcb ,其长度为5。 回文:正着念,反着念都一样 暴力解不容易,要解决长度为奇数和长度为偶数 回文的问题 以每个位置为中心,向两边扩。 但是偶回文就扩不了了! 下图,无论是从哪一个数字开始扩,回文长度 都只能是1 这种情况下,我们只能向这个字符串中加东西! 比如这种情况,既有奇回文,又有偶回文 具体怎么插入呢?如下图: 数字的含义 是该位置的回文长度 最长回文就是最大值除以2

Mr_zhang66的博客 1793

manacher算法

Manacher 算法是一种用于寻找字符串中的高效算法,时间复杂度为。

Panda!!!!!! 894

【算法】——Manacher Algorithm(马拉车算法)

一、马拉车算法来源 马拉车算法Manacher‘s Algorithm是用来查找一个字符串的最长回文子串的线性方法,由一个叫Manacher的人在1975年发明的,这个方法的最大贡献是在于将时间复杂度提升到了线性,这是非常了不起的。对于回文串想必大家都不陌生,就是正读反读都一样的字符串,比如 "bob", "level", "noon" 等等,那么如何在一个字符串中找出最长回文子...

汤庆 8404

manacher算法(仅用于回文)——算法详解

算法简介:manacher算法是一个能够在线性时间内得到一个字符串中最长回文子串的算法,性能比其他的算法,如字符串哈希还要优秀,且不会被造数据卡住。是处理回文串最有效的工具。 算法分析: 1.首先有一个问题,那就是我们如何处理奇数回文串和偶数回文串这两种不同情况。我们可以采取如下处理方式: 假设存在一个字符串str:abbabba 将其转化为s:$#a#b#b#a#b#b#a#& 原则是首尾两个字符不同,和中间的字符也不同(防止出现访问越界),中间所有字符相同。 2.现在我们来观察一下 以我们

风中的微尘的博客 442

【字符串】马拉车(Manacher)算法

因为字符串长度的奇偶性,回文子串的中心可能是一个字符,也可能是两个字符中间的位置,所以为了解决这个问题,我们在每两个字符之间加一个。已经计算过了,如果以 j 为中心的回文子串在以 c 为中心的回文子串中时,我们可以直接把。,我们可以去找 i 关于 c 的对称点(记为 j),因为我们是从左往右计算的,所以。对于以每一个位置为中心点的时候单独计算,复杂度很大,马拉车可以对其进行很好地优化。此时已经有比以 c 为中心的回文子串更靠右的回文子串了,就把。马拉车算法可以求出一个字符串中的最长回文子串,时间复杂度。

Texcavator的博客 1065
上一篇: <队内胡策> 2017.10.10 (贪心+二分答案+DP)
下一篇: openjudge noi 9278 旅行
Loi_Mapleleaf
博客等级 码龄10年 17粉丝 72原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值