省选集训-字符串杂题

news/2025/2/6 20:38:37/文章来源:https://www.cnblogs.com/spdarkle/p/18701644

省选集训-字符串杂题

基础子串结构太ex就不看了

CF1827C

考虑如何将一个由若干偶回文串拼接而成的串分解开。

容易发现每次从后往前删掉最短回文串就是对的。

所以问题变成求 \(l_i\) 表示 \([l_i,i]\) 是以 \(i\) 为结尾的最短回文串位置。

则可以 \(dp\) 计算,\(dp_i=dp_{l_i-1}+1\)\(ans=\sum dp_i\)

\(l\) 可以使用 manacher 然后做区间染色得到。

CF1913F

屑题。

考虑计算出 \(c_x\) 表示改变 \(a_x\) 后消失的回文串数量,\(w_{i,x}\) 表示将 \(a_i\) 改为 \(x\) 后新增的回文串数量即可计算出答案。

考虑使用 manacher 求出原本的各个回文中心以及回文半径,将其往外扩张一个单位后(这个位置失配)再使用哈希求出最长长度,就可以对 \(w\) 进行计算了。

以及 \(c\) 的计算事实上根据回文半径可以变成区间加等差数列。

考虑求出 \(c\) 的二阶差分,然后计算即可。

区间加等差数列别推错了,就尴尬了。

P10716

注意到 \(A\) 是该前缀的 border,并且 \(B\) 可以为空。

那么找到最长的 \(border\) 后,这个串的 \(border\) 个数即为所求。

考虑失配树(\(nxt\) 树),也即 \((i,k)\) 的询问是找到 \(i\) 合法的最近祖先。

可以倍增,问题变为如何判断。

注意到调和级数求和,因此对于每个前缀 \([1,i]\),都预处理出 \(k=1\sim \lfloor\frac{n}{i}\rfloor\) 的最短前缀长度(可能没这么多次)。

那么就只剩下一个判断了。

找的话,\(pos\) 后的下一次出现位置可以变成子树内大于某个值的最小编号寻找,失配树上线段树合并即可。

P11150

关于讲课ppt是错的这件事。

要最小化原串的字典序,那么首先就要找到改后第一个与原串不同的位置 \(np\),让这个位置尽量小。

可以对原串建立一个SAM,然后将 \(B\) 在 SAM 上逐位匹配(相当于枚举 \(np\) 这个位置由 \(B\) 的哪一个位置做出贡献)

那么首先就要求了 \(np\) 最小。在 \(np\) 相同时,我们再哈希判断两个不同的 \(B\) 接入位置谁更优。

这样我们就找到了一个最优的接入位置 \(r\),考虑将其变为最小的接入位置。

稍加画图可以发现,对于效果相同的接入位置,那么一定是原串匹配上了 \(B\) 的循环节。

所以倍增往前跳的循环节个数,然后哈希求出新的方案里得到的新串哈希值是否与原本串相同即可。

CF1975G

首先做一些讨论:

  1. \(s,t\) 不含 \(*\),可以直接判断
  2. \(s,t\) 都含 \(*\),将第一个 \(*\) 前面的以及最后一个 \(*\) 后面的位置进行匹配判断,判断通过显然有解。
  3. \(s,t\) 仅有一个含 \(*\),类似 \(2.\) 先去掉第一个 \(*\) 以及最后一个 \(*\) 前/后面的串。

那么一般地,可以看作 \(s=*s_1*s_2*\dots *s_m*\)\(t\) 不含 \(*\) 进行匹配。

贪心地,我们动态维护 \(p\),逐个将 \(s_i\)\(t[p,n]\) 进行匹配,并将 \(p\) 置为第一个匹配到的位置之后(也就是逐个匹配)

考虑到单次匹配代价太大,需要将单次匹配复杂度降至 \(|s_i|\) 级别。

很厉害的地方是将 \(t[p,p+2|s|)\) 拿出来匹配,不管有没有匹配位置,\(p\) 至少增加 \(|s|\)

然后就考虑 \(|s|\) 级别复杂度匹配,关于带通配符的字符串匹配,可以考虑 NTT,也就是将每个字符赋权 \(w_i\),通配符为 \(0\),计算:

\[f_i=\sum_{k=0}^{|s|-1}s_{k}t_{p+i+k}(s_k-t_{p+i_k})^2 \]

这可以拆为三次差卷积计算。

P11291

注意到 \(R\) 可以为空,所以固定 \((l,r)\)\(k\) 是一段区间,固定 \((l,k)\)\(r\) 也是一段区间。

但是性质更好的是固定 \((l,k)\),不妨设 \(f_{l,k}\) 为其对应的最大 \(r\),设 \(r_i\) 为最大的满足 \([i,r_i]\) 是好串的值。

则显然 \(f_{l,k}=\max_{i\le j\le f_{l,k-1}}(r_j)=\max_{i\le j\le r_i}f_{j+1,k-1},f_{l,1}=r_l\)

但是注意到最远的,那么一定 \(r\) 所有的都不为空,那么对于最右侧的形式,以 \(k=3\) 为例,有:

\(f_{l,3}=\max_{i\le j\le r_i+1}f_{j,2}=\max_{i\le j\le r_i}\max_{j\le k\le r_{j+1}}r_{k}\)

而注意到对于跳跃方案:\(l\to j\to k\to \dots\) 每一步都应当是最优化的。

形式地说,设 \(to_i\)\(\max_{i\le j\le r_i+1} r_j\) 取到最优的 \(j\)\(f_{l,2}\) 转移时用了 \(to_l\)\(f_{l,3}\) 转移时在 \([l,f_{l,2}+1]\) 里找一个 \(to\) 最大的转移,而这个位置显然不会低于 \(to_l\)\(f\) 单调不降),因此就变成了 \(to_l\)\(f_{2}\) 转移,也就是找到的位置是 \(to_{to_l}\)

因此就变成了跳 \(to\) 的问题,建 \(to\) 树,就变成了树上统计的问题。

对于问题一是好做的,相当于只需要 dfs 时维护一个链和,而问题二也可以变成若干区间加等差数列,可以二阶差分解决。

CF1975H

考虑到如果我们要让最大子串最小,那么设 \(z\) 是最大字符,重排后一定形如 \(z+s_1+z+s_2+\dots +s_m+z\) 的形式。

最大子串一定是一个后缀,这是显然的。

因此这相当于是确定下了后缀的最后面是一个 \(z\),然后我们继续将 \(z+s_i\) 视作一个字符,变成了子问题。

所以当最大字符数小于等于其余字符数的时候,我们找到了一个让问题规模减半的方法。

\(s_i\) 应当如何划分?注意到按目前顺序,也自然有 \(s\) 的字典序不降的说法,且每个 \(s\) 的第一个字符应当组成原本其余字符排序后的一个前缀。

事实上,考虑这样一个贪心:

维护 \(i,p\),初始化为 都为 \(1\),设其余字符排序后是 \(a\),那么我们每次将 \([p,m]\)\(s\) 按顺序加上 $a_i,a_{i+1},a_{i+2}\dots $,这样填完了一轮之后再将 \(p\) 变成当前末尾最大的 \(s\) 的首次出现为止(也即 \(s_{p-1}<s_p=s_{p+1}=\dots =s_m\)

这样做显然是对的,我们保证了前面尽可能小,且后续越往后越大,且“变大量”更小。

那么在最大字符数大于其余字符数后怎么办?事实上可以采用同样的处理办法,但是我们要预处理处理结果(保证复杂度)

这个处理结果相当于每个其余字符前面多了相同数量且最多个 \(z\),同时还空余出了若干个 \(z\) 作为余下的最大字符,然后末尾也都出了这么多个 \(z\)

保证每次递归问题规模减半,问题解决。

CF2053G

考虑单次操作的过程,不妨设长串为 \(s_1\),短串为 \(s_0\)

\(s_0,s_1\) 都可以表达为一个串 \(t\) 重复至少一次得到,则可以通过 KMP 求出原串的最小循环节直接判断。

那么就只需要处理 \(s_0,s_1\) 无共同循环节的情况了。

不妨设 \(s_1=s_0^k+c\),且 \(k\) 最大,也即 \(s_0\) 不是 \(c\) 的前缀,我们先不断贪心匹配短串,当短串失配时,再撤回若干次匹配,换用长串匹配。

显然,我们至少需要撤回 \(k\) 次短串匹配,然后尝试用长串匹配。

同时,我们声称,我们至多需要撤回 \(k+1\) 次。

  1. 当撤回 \(k+1\) 次可以匹配,说明 \(c\)\(s_0\) 的真前缀。

  2. 如果撤回 \(k+2\) 次可以匹配,则撤回 \(k+1\) 次也可以匹配(这是显然的)

    那么这就说明 \(s_1+s_0=s_0+s_1\),也就说明 \(c\)\(s_0,s_1\) 的循环节,与 \(s_0,s_1\) 无共同循环节不符。

  3. 同理撤回更多次的情况也是一样的。

同时,如果撤回 \(k\) 次与撤回 \(k+1\) 次都可以匹配,我们优先撤回 \(k\) 次,因为产生差异只能是撤回用 \(s_1\) 后连用 \(s_1\) 进行匹配,也就是撤回后后面的串被匹配为 \(s_1+s_1\),如果撤回 \(k+1\) 这样做遇上这种情况就被封死了(会连续撤回),而撤回 \(k\) 就不会出现这种情况,并且如果也被封死,撤回 \(k+1\) 次的决策也会寄。

那么我们每次跳跃都是 \(|s_0|\) 的,总复杂度单 log,而长串的匹配由于 \(|s_1|\ge \frac{n}{2}\),因此总匹配次数是 \(O(\frac{m}{n}·n)=O(m)\) 的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/879803.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[megatron代码阅读] 2. TP和PP实现

megatron 源码阅读第二篇, 看了TP和PP的对应实现训练并行实现 TensorParallel 张量并行代码路径, 代码路径: megatron/core/tensor_parallel 主要包含Linear / VocabEmbedding / cross_entropy 三部分. Linear 参数初始化 如果是从checkpoint热启, perform_initialization需要打…

2024.2.6鲜花

初探牛顿迭代?推歌 《以恋结缘》 诚、意地の悪い神の所业か? 奇迹?縁?袂触合う不思议 花ひとひら揺れて 不意に宿ってた うなじ解いてく春风 戯れはそこそこに 恋手ほどきしてくだしゃんせ 汤気にほんのり頬染て 夜风に愿ふ …いざ!!蝶と舞ひ花となりて 衣を乱して祓いま…

megatron 2. TP和PP实现

megatron 源码阅读第二篇, 看了TP和PP的对应实现训练并行实现 TensorParallel 张量并行代码路径, 代码路径: megatron/core/tensor_parallel 主要包含Linear / VocabEmbedding / cross_entropy 三部分. Linear 参数初始化 如果是从checkpoint热启, perform_initialization需要打…

【Azure Policy】当Azure策略组中存在多个修正任务时候时的批量处理办法

问题描述 在分配一组策略中包含了很多修正任务时候,从门户上,只能选择一个修正任务执行。 如下图:是否有好的办法,执行全部的修正任务呢?问题解答 从Azure门户的设计来看,只能选择一个修正任务是设计使然。如果想批量执行全部的修正任务,需要使用PowerShell脚本来循环执…

Kotlin空安全

前言 访问空引用的成员变量就会导致空指针异常,在Java中被称作NullPointerException,简称NPE,Kotlin中NPE产生的原因只可能是以下几种:显式调用 throw NullPointerException()使用了!!操作符数据在初始化时不一致,例如:传递一个在构造函数中出现的未初始化的 this 并用于…

Kotlin控制流程

条件与循环 if表达式 Kotlin中的if与Java中的if大致上都差不多,但是Kotlin中没有三元运算符(A ? B : C),可以用if表达式作为代替,例如: Java int a = int a = System.currentTimeMillis() % 2 == 1L ? 1 : 0; Kotlin val a = if (System.currentTimeMillis() % 2 == 1L…

第一次用Markdown

标题 标题2 标题3 标题4 字体 字体 字体姓名 性别 年龄张三 男 20![das]() baidu

【测试基础】web3.0介绍

web3.0介绍 Web3.0也被称为下一代互联网,是对当前互联网(Web2.0)的演进和升级。其目标是实现一个更加去中心化、安全、用户拥有数据主权且具有更好互操作性的互联网环境。Web3.0的核心技术包括区块链、智能合约和加密货币等。 web2.0与web3.0区别 Web2.0和Web3.0的主要区别在…

区块链原理、技术与实践

区块链介绍 区块链是一种分布式账本技术,允许多个参与者共同维护一个不断增长的数据记录列表,每个区块包含一系列交易记录,并通过密码学方法与前一个区块链接起来,形成一个不可篡改和不可逆的链条。 这种基于共识的机制使得区块链具有高度的安全性和透明性。 区块链与传统W…

《高效能人士的七个习惯》

情感账户 勇气和体谅 大石头 自传式回应、同理心倾听:用你的话反映他们的感受和意思,而不是去评论、去判断是否正确

高效能人士的七个习惯

情感账户 勇气和体谅 大石头 自传式回应、同理心倾听:用你的话反映他们的感受和意思,而不是去评论、去判断是否正确

新春“码”启 | Cocos 3D 微信小游戏(第5天):分包构建和上传发布(完美收官)

新春开发 Cocos 3D 微信小游戏计划的第 5 天,详细介绍了如何利用Cocos Creator开发并发布一款3D微信小游戏,包括游戏状态机的设计理念,和微信小游戏主包大小限制时的解决方案——分包策略。从游戏设计、开发、调试到最后成功发布的全过程,为想要进入微信小游戏开发领域的开…