首页 > 其他分享 >[OI] 欢夏!邪龙?马拉车!

[OI] 欢夏!邪龙?马拉车!

时间:2024-08-07 17:50:57浏览次数:5  
标签:对称点 邪龙 OI 欢夏 转移 枚举 字符串 我们 回文

标题来自原神

算法概述

Maracher 算法

用途:寻找回文串,最板子的情况下用于字符串的回文子串计数

给定一个字符串 \(S\),求出它全部的回文子串

容易想到一种暴力的 \(n^{2}\) 做法,即枚举全部中心点,开双指针向两边扩展,每扩展一次就提供 \(1\) 的贡献.

事实上,对于这样的算法来说,判断偶回文串会不太方便:因为它没有中心点.

因此,我们考虑在原字符串里加入一些莫名其妙的字符,如下:

cthoiissb
c#t#h#o#i#i#s#s#b

这样做,我们发现,当枚举原字符串内的点作为中心点时,就相当于在枚举奇回文子串,当枚举特殊字符作为中心点时,就相当于在枚举偶回文子串. 我们通过上述方法完成了对奇偶子串的统一.

下面我们来考虑对进行的转移进行优化

首先我们引入一些概念:

定义回文半径表示回文串的长度除以二的值(显然,在处理之后,回文串全都变成了奇回文串,因此直接向下取整即可),我们这样定义是因为处理后的回文半径长等于处理前的回文串长度减一,如下:

cthtc   length=5
c#t#h#t#c length=4

类似地,我们还可以求出该回文串在原串中的位置:

oicthtc
o#i#c#t#h#t#c length=4
       [8]

可以发现,cthtc 的对称中心 h 在原字符串中的位置为 \(5\)(以下默认下标从 \(0\) 开始),在处理后的字符串中的位置为 \(8\),而回文半径长为 \(4\),考虑到 \(8+1-4=5\),发现再多举几组也是如此的性质,即 “原字符串位置等于处理后字符串位置加一减去回文半径”,考虑到这样有点麻烦,因此在处理后的字符串前插入一个不同的字符(也是为了防止在 \(p=0\) 时访问负数下标),实际上如果保守一点的话,末尾也是需要插入特殊字符,只不过因为末尾有一个 \0,因此不需要插入. 需要注意的是,如果真的要插入的话,首位字符不能相同,否则直接就把他们两个匹配上了,会影响答案.

到现在我们的算法还是 \(n^{2}\) 的,下面我们来考虑优化这种转移.

图源

图例中的 \(T\) 表示了一种可能的字符串,下方的每一位的 \(P\) 表示了以当前位为中心的最长回文半径. 一般来说,这个 \(P\) 数组需要我们从头到尾扫一遍来求,这一点我们无从优化,我们来考虑如何才能从之前的状态跳到当前的状态.

如图,我们已经求出了一部分 \(P\) 的值,注意到图中有一个很大的 \(P_{11}=9\),我们考虑利用一下它,因此用虚线标出它的中心与左右边界. 现在我们的目标是求出 \(P_{13}\)

假如 \(P_{11}\) 左右两边对称的话,可以想到我们只需要找到需要求的点在另一边的对称点,那么对称点的 \(P\) 值一定就也是当前点的 \(P\) 值:因为回文的性质,既然对称点是回文,对称过来也一定是回文,并且因为之前求的是最大值,因此也不存在一个更大的值了,所以直接转移即可.

下面我们再来考虑另一种情况:

现在的目标是求 \(P_{15}\),按照刚才的思路,现在我们应该去找对称点 \(P_{7}\),但是我们发现此时无法直接进行转移.

刚才我们转移是建立在一个很大的回文区间 \(P_{11}=9\) 上的,因为两边的回文区间全部都在这个大的回文区间内,因此我们才能保证两边的字符是相等的. 现在区间超出了大的对称区间的范围,因此不能保证超出范围的部分是相等的,也就不能直接转移了.

不过这样的情况还是有利用价值的,考虑可以先把能保证相等的转移了,即转移到大区间的边界,剩下的没有办法,可以直接进行暴力转移,为下一次转移助力. 可以证明这样做的复杂度是 \(O(n)\) 的.

习题

P3805 模板

To be added

标签:对称点,邪龙,OI,欢夏,转移,枚举,字符串,我们,回文
From: https://www.cnblogs.com/HaneDaCafe/p/18347542

相关文章

  • macOS Sequoia Beta 隐藏款新壁纸
    苹果发布了macOSSequoiaBeta5,有一些Mac用户安装后发现了一款新的森林主题壁纸。但是,该壁纸还未正式发布,而且还隐藏在系统文件中。新壁纸:Sequoia-Sunrise1920×1080266KB隐藏文件夹位置以及新壁纸的.heic和.mov格式 (动态模式)下载链接「包含标准的macOSS......
  • Java计算机毕业设计基于Android的公交线路状态查询系统(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着城市化进程的加速,公共交通系统成为了城市居民日常出行不可或缺的一部分。然而,传统的公交线路查询方式往往依赖于纸质地图、公交站牌或电话查询,这......
  • 【NOI】C++算法设计入门之穷举
    文章目录前言一、概念1.导入2.概念二、例题讲解1.简单穷举问题:1015.鸡兔同笼问题问题:1351.买公园门票问题:1016.买小猫小狗问题:1220.买糕点问题:1396.开学大采购?2.嵌套穷举问题:1022.百钱百鸡问题问题:1024.购买文具问题:1249.搬砖问题问题:1250.马克思手稿的问题......
  • 【题解】Solution Set - NOIP2024集训Day1 数据结构
    【题解】SolutionSet-NOIP2024集训Day1数据结构https://www.becoder.com.cn/contest/5429「CF1428F」FruitSequences线段树是可以维护区间最长子段的1。记固定右端点在\(i\),的答案为\(f_i\)。那么:\(a_i=0\),\(f_i=f_{i-1}\);\(a_i=1\),打一个单调栈维护所有的最长子......
  • Android开发基础04-Java 和 Kotlin
    引言Java和Kotlin是两种主要用于Android开发的编程语言。理解它们的基本概念、特点、优缺点及常见用法,对Android开发者来说非常重要。1.Java基本概念Java是一种面向对象、跨平台的编程语言,于1995年由SunMicrosystems(现为Oracle)发布。它的设计理念是“WriteOnce,Ru......
  • Android开发基础02-零基础学习Android指南
    学习路线1.理解Android开发基础1.1理解Android平台架构先从高层次上了解Android操作系统的架构,包括应用层、应用框架层、库和Android运行时、Linux内核。了解这些层次及其作用,会帮你更好地理解Android的工作原理。1.2学习Java乐Kotlin语言Java和Kotlin......
  • Flink实战(10)-checkpoint容错保证
    0前言程序在Flink集群运行,某个算子因为某些原因出现故障,如何处理在故障恢复后,如何保证数据状态,和故障发生之前的数据状态一致?1什么是checkpoint(检查点)?Checkpoint能生成快照(Snapshot)。若Flink程序崩溃,重新运行程序时可以有选择地从这些快照进行恢复。Checkpoin......
  • android源码编译
    搭建编译环境Ubuntu12.04更新源debhttp://old-releases.ubuntu.com/ubuntuprecisemainuniverserestrictedmultiversedebhttp://old-releases.ubuntu.com/ubuntuprecise-securityuniversemainmultiverserestricteddebhttp://old-releases.ubuntu.com/ubuntupre......
  • P3200 [HNOI2009] 有趣的数列
    哇,太恶心了思路首先我们将题意简化,简化后为对于任意一个偶数位所填数必然大于等于自己的下标,那么考虑填数,如果填的偶数比奇数多,那么此时要么填尽偶数后失败,或者下一个位置填奇数就炸,比如偶数刚好多一个,那么必然有一个偶数放在了奇数位,那么本来下一个要填的偶数往前移了一个,导致......
  • [WACV2022]Addressing out-of-distribution label noise in webly-labelled data
    该论文考虑了一个现实的场景:数据集来自网络爬虫,即存在开集噪声OOD样本和闭集噪声ID样本。作者提出了一个简单但有效的策略:通过新设计的指标区分OOD样本,并对OOD样本软化(soften)弥补与干净样本的差距,该方法称为:DynamicSofteningofOut-of-distributionSamples(DSOS)。真实世界噪......