10月杂题
还是得写写杂题,初三赛季说明这对我是 buff 啊。
这次 CSP-S 再次检验王者是超级 debuff!!!
1. P7830 [CCO2021] Through Another Maze Darkly
感受一下,每次从根开始绕一圈回去,这个圈会越来越大,直到大小变成 。
考虑求出每个边在最后一个圈内入和出的时间(就是欧拉序),你会发现每次走的一圈是这个序列的子序列。那对于一次询问,先二分这是哪一圈走的;然后离线下来,则要支持插入和查 k 小。这是容易的。
2.P7949 [✗✓OI R1] 左方之地
考虑求出 的数形成的线性基。不妨令 ,则每个 都是要选出线性基的一个子集。这些子集要互不相同。这就转化成了 的问题。
3.ARC129E Yet Another Minimization
主要是怎么刻画这个权值,对于每对 ,考虑把 拆成数轴上的若干段,就是把 和 这些当成关键点之后,考虑两个相邻的关键点。
设第 个位置取的 是第 小的。则我们能把权值写成: 若 ,则会出现 的代价。还有一些 时,会出现 的代价。这个就是切糕了。
4.AGC044D Guess the Password
编辑距离这个东西很抽象,尝试用它做一些简单的事情。
首先用全 a 串就能得到 S 中 a 的个数,其他字符同理。
并且我们可以判断一个串是否是 的子序列。就是看编辑距离是不是 。
看到 850 这个限制,感受到它是 nlogn 状物,于是我们尝试分治。
就是说先想一下 ab 串怎么做,设 的个数为 ,我们在 a 后面接 个 b ,如果这个是 S 子序列,说明 S 第一个位置是 a ,否则是 b 。
现在有多个串了,其实就可以分治做,令 为, 内的字符拼成的串,从下往上,用上面的 ab 串方法拼就好了。
5.CF1870G MEXanization
先想怎么算答案,考虑二分。我们最后要凑出 ,那最后一步一定包含 到 。而如果中间某个数 不存在,则要求 至少有 个。所以有这样一个算法,先把 的都变成 ,然后从 到 扫一遍,维护 表示后面的数都需要至少 个。考虑此时扫到的数出现次数为 。如果 ,则 增大 ;否则的话我们把多余的 个数都变成 。
发现如果 合法,那 只会增大 次,因为 后,如果位置也 就凑不够了。
并且随着数的加入, 只会越来越大,我们就只需要 次 check 。每次 check 用线段树二分加速这个过程,即找到第一个 的位置。同时要更新 的个数。这里线段树二分写成自下往上的话,能证明总复杂度为 。
6.CF1870H Standard Graph Problem
跑一遍最小树形图,我们其实建了一张新图,形如一棵树,就是每次缩环时我们建了一个新点来表示这个环,它的儿子就是环上的点。
发现最后的点集中如果含有 ,那 到根的边都不用选。这就成了一个小清新 ds 了。
7.AT_joisc2016_h 回転寿司
先考虑 ,用堆维护 中的数即可。所以我们考虑分块,对每个块维护一个堆。那一次操作中,处理整块很容易,但处理散块时,我们就需要得到:这个块之前做了若干整块操作后每个点的值是多少。发现这是和原问题对称的,就做完了。
8.AGC025E Walking on a Tree
考虑对每条路径连一条 的边,如果每个点度数都是偶数,那直接跑一遍欧拉回路显然是对的。现在我们尝试调整,就是通过加树边,把度数调整成上面的形式。这样跑出来回路后,考虑对于一组树边 ,能影响它的新增边只有 本身,所以去掉新增边后一定合法。
10.ARC142E Pairing Wizards
先把题中的限制化简一下。不妨令 ,则 ,且 或 。处理第一个限制就是调整一下 。看到第二个限制,一开始想直接像切糕那样做,但最小割的局限性使得它只能做 这样的限制。但这个题特殊点在于它有一个 。我们能把点分成两类:当前 的为第一类,否则为第二类。显然对每个限制, 一定是第一类, 可能是第二类。
对于第一类点 ,我们建点 ,如果它与 联通就代表最终 。为了表示出这个效果,需要连边 。
对于第二类点 ,我们这样处理限制:建立新点 ,连边 ,代表要么我自己提升,解决限制,要么丢给所有相连的 解决限制。
跑最小割即可。
11.P4785 [BalticOI 2016 Day2] 交换
分类讨论根的情况,发现有一种情况不能直接处理,就是 中的最小值在 上。则操作后,我们无法确定另外两个数 该放 还是 。怎么办呢,令 ,考虑 放在哪边,能使最后 处在的位置更小。发现这样就能比对了。就是要计算一个 表示当前 权值为 ,操作子树 , 最后的位置,还是利用上面的讨论来算。发现可能的状态只有 个,因为这里一定存在祖孙关系。就做完了。
12.AGC022F Checkers
以前一直看不懂这个题的题解,想来想去想不清楚,今天重看,发现自己思路一气呵成啊。首先翻译一下题意,就是有一个 个结点的二叉树,其中有 个叶子结点代表 。我们设 的边权值为 , 的边权值为 。那两个树不同,当且仅当存在某个叶子结点,使得它到根的边权之积不同。
每个这样的积都能表示成 的形式。其中 。考虑怎么计数,我们先指定每个叶子的权值,然后尝试 check 能否构造出一棵树。一次合并其实就是把 和 合并成 。那 check 就是按 从大往小贪心地合并,因为最大的 无法再改变。
这样按 从大往小,就有一个 dp :记 表示我到当前层,其中 的有 个点, 有 个点。考虑转移,就是枚举下一层 和 的个数 。 假设 ,那转移合法的充要条件是: , 不做限制。先说必要,因为当前层的 个 只能使 至多增加 (把下一层的 变成 ) 。再说充要,就是我们每次取出当前层的一个 和一个 ,再取出下一层的一个 ,先合并 再合并 即可。下一层这个点仍然是 ,但它消灭了当前层的两个点!再对剩下的做操作就行了。发现下一层最后的状态也是固定的。
再观察一下上面的形式,发现 dp 只需要记 就行了,于是复杂度优化到了 。
最后答案为 ,因为最上面一层只能有 个点,而且需要最后符号是正的。这样就做完了!
13.P6700 [PA 2015 Final] Edycja
14.P4786 [BalkanOI2018] Election
考虑 的贪心:令 S 为 1,T 为 -1,从左往右扫,如果前缀和为负就把 T 删了。再倒着扫,后缀和为负就把 T 删了。
设 为前缀和, 为后缀和。则第一轮我们操作次数为 ,考虑第二轮中 的改变,有 。第二轮操作次数为 。加起来,发现它就是 。就是最大子段和,用线段树维护即可。
15.P9447 [ICPC2021 WF] Spider Walk
直接 dp ,每次要交换 并对值进行更新。更新形如 。
考虑此时很多转移都是没必要的, 和 中一定有一个为 或 。对于 为 或 ,用线段树维护即可;对于 为 或 ,发现只需要用 和 更新 即可,因为其他位置的转移都可以拆成两段: ,而第一段已经在之前转移过了。 同理。
16.P9341 [JOISC 2023 Day4] Security Guard
首先有结论:树的答案为 。那 就是最小生成树。在这个基础上调整,就是每次找到一条边 断掉,假设 与 联通,就找到 一段的最小点 并连边 。现在考虑怎么优化,正做是困难的,因为它在删边。考虑倒着做,就是 时一定是以 为根的菊花,在这个基础上加树边,我们要找到对答案贡献最好的边:当前一条边的权值是, , 是 所在联通块的点集。这个就容易了,用 set 维护这些边,每次加边时会合并两个联通块,合并之后需找出这个联通块对外的最小边,可并堆即可。
17.P8553 醒来
18.P5659 [CSP-S2019] 树上的数
发现我们每指定一个权值要从 换到 ,就会产生一些限制:考虑 到 的路径,这上面的第一条边必须是与 相邻的边中第一个被删的;最后一条边必须是与 相邻的边中最后一个被删的;对于中间的点,删完前一个边后必须立马删后一条边。
确定了每个点与之相邻的边的删边顺序后,是一定存在一组合法方案的(肯定连不出环)。用链表维护这些限制,每次枚举 查看是否合法即可。复杂度 。
19.ABC234Ex Enumerate Pairs
有点神奇的,就是说把整个图划分成若干 的块,那可能的点对只会在一个块内/两个相邻的块。下面我们说明,直接枚举上面两种情况,复杂度正确。对于一个块内,如果存在 个点,那一定有 个点对,原因是对这个块能划分成 个 的小块,存在至少一个小块有 个点,而这些点距离不超过 ,一定合法。再考虑相邻的块,设两个块的点个数为 ,我们需要枚举 次。考虑 ,发现每个 带的常数 。这样就做完了,复杂度 , 是不大的常数。
20.P4218 [CTSC2010] 珠宝商
处理路径,我们尝试点分治,每段路径都由两段拼起来。对于第一段,我们处理出它在文本串中的哪些位置出现了,对每个匹配的位置 ,让 加上 ,第二段同理计算 ,最后统计 即可。现在就是要加速计算这两个东西。考虑“第一段”的这些串是怎么构成的,其实就是 dfs 一遍,当前的串 是由 前面添加一个字符形成的。如果是在后面加就做完了:建 SAM 来匹配这个串,匹配到每个点时都在 fail 树上做一个子树加,由于只用最后查一遍,复杂度是 的。现在是前面加,我们怎么搞呢。需要用另一种方式来找到当前匹配到的节点:其实这个时候就是走到后缀树上的儿子,要理解好 SAM 呀。
此时总复杂度是 ,寄掉了,考虑优化:如果当前大小已经 了,我们直接枚举每一个点为路径的一个端点, dfs 并计算答案即可,这个是 的。对 的还是像上面做,复杂度就是 的,取 即可做到 。
21.P9062 [Ynoi2002] Adaptive Hsearch&Lsearch
考虑把平面分成 的网格,然后有结论:对每个点我们只需要找与它在相同网格 or 在相邻网格的编号相邻的 个点即可。于是找出点对后二维偏序即可,复杂度 。
22.P8885 「JEOI-R1」子序列
先考虑对给定的序列计算子序列个数,我们设 为以 结尾的子序列个数, 为当前子序列总个数,则转移是 ,那在模 意义下就是交换 和 。初始状态是 ,那我们只需要记 的位置即可。
考虑对给定的串怎么计算合法的子段个数。与 CSP-S T2 类似的,考虑一个子段 合法,当且仅当跑完 后 的位置与 相同。那我们把这个串跑一遍,统计 表示有多少个前缀使得 跑完后 的位置在 ,则合法子段有 个。由于只关心这个式子的奇偶性,我们记下来 模 的余数即可。
计数就是把上面的 压成状态捏。记录当前 的位置是没必要的,我们可以直接说 是有多少个 满足最后 位置在 ,则每次是交换 并让 加 。但是还能优化:由于长度固定时 是固定的,只需记录 ;然后,我们也不需要记录模 的余数,记模 的余数并在记一个 表示当前的答案。这样状态就是 了。算子段答案就是用猫树,先算左边,再算右边,拼起来即可。注意这里有细节:需要枚举 的奇偶,不然就不好整了。
23.AGC044E Random Pawn
我们能断环为链:找到最大的 ,在 处断开即可,因为走到 一定要停下。现在有 dp 方程: 其中 。
感受一下,这个式子和凸有些相关。如果 全是 ,那把 的上凸包求出来即可。现在考虑转化一下式子,即我们设 ,那有 。那就是让 即可满足上面的式子。 和 都是能任意取的,那 也是任意取的,然后递推后面的 即可,这个题就做完了。
24.AGC011E Increasing Numbers
主要就是这个形式的数能拆成若干 的和捏。那把原来的 乘上 ,再枚举用 个数凑。那就是 。从小到大枚举 ,动态维护 即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App