[Codeforces Round 1114 (Div. 3)] 题解

额因为太晚了所以场上没有做 F 和 G,补题的时候看了一眼发现都很唐。

A. Riptide

直接模拟即可。

Upd:好像 tty 说有 \(\mathcal O(1)\) 的做法,答案是 \(\min(v_3-v_2,v_2-v_1)\),场上懒得想直接模拟了。

B. Evanescent

\(f(s)\) 相当于把字符串 \(s\) 每一个连续的段压缩成一个,所以删掉一个字符会减少连续段的数量当且仅当该连独断大小为 \(1\),此时才会有 \(|f(s')|<|f(s)|\)。但删除这个字符对左右连续段也是有影响的,若左右连续段字符相同,答案就会减少 \(2\),否则减少 \(1\),直接做是 \(\mathcal O(n)\) 的。

C1. Marenol (easy version)

注意到奇偶位置独立,那么判断是否能转化是简单的,即两个串 \(0\) 的个数相同,\(1\) 的个数相同,奇数位的 \(1\) 相同就足够了,直接扫一遍是 \(\mathcal O(n)\) 的。

C2. Marenol (hard version)

先只管 \(1\),因为除了 \(1\) 都是 \(0\)。

还是先把奇偶位置区分,分别计算答案,以奇数位上的 \(1\) 为例,首先如果两个串奇数位上 \(1\) 个数不同肯定无解,个数相同的前提下我们让 \(a_{i,1}\) 都变成 \(b_{i,1}\),步数是 \(\sum |a_{i,1}-b_{i,1}|\) 的,偶数位同理,这样统计是 \(\mathcal O(n)\) 的。

D. Silhouette

首先对于 \(a_i=a_j\),必有 \(b_i=b_j\),反之亦然。那么将最终的 \(\{b_i\}\) 去重排序后,大概是一个前缀和状物。

记 \(\{a_i\}\) 去重排序后为 \(\{s_i\}\),\(\{b_i\}\) 去重排序后为 \(\{t_i\}\),那么由于 \(t_{i+1}-t_i=s_ic_i\),那么就可以构造出 \(s_i=\frac{t_{i+1}-t_i}{c_i}\),如果 \(c_i \nmid (t_{i+1}-t_i)\) 或者除完之后不满足单调性就无解,最后一个 \(s_k=s_{k-1}+1\) 即可让字典序最小。其中 \(c_i\) 表示重复的 \(a_i\) 或者说重复的 \(b_i\) 的个数。

E. Chronostasis

注意到差分数组的前缀和就是原数组,尝试模拟从 \(b\) 中取出元素做前缀和的过程,首先 \(a_i \ge 1\),我们可以把 \(b\) 放进一个 std::multiset 里面 lower_bound 先把第一个 \(\ge 1\) 的位置取出来作为起点,然后遍历这个可重集的同时记录一下当前的前缀和 \(s\),而此时 \(a_i \ge 1\) 等价于 \(a_{i-1}+b_i \ge 1\),即 \(b_i \ge 1-a_{i-1}\),然而这里的 \(a_{i-1}\) 相当于我们记录的前缀和 \(s\),所以直接在可重集里面 lower_bound 一个最小的 \(b_i \ge 1-s\),更新前缀和并放进答案即可,扫一遍是 \(\mathcal O(n \log n)\) 的。

F. Whiplash

观察两次操作 \(i\) 和 \(j\) 后带来的结果,这里 \(k\) 指的是其他的非 \(i\) 和 \(j\) 下标。首先对于对 \(i\) 的一次操作:

  • \(a_i \gets a_i\)
  • \(a_j \gets a_j \oplus a_i\)
  • \(a_k \gets a_k \oplus a_i\)

然后对于对 \(j\) 的一次操作:

  • \(a_i \gets a_i \oplus (a_j \oplus a_i)=a_j\)
  • \(a_j \gets a_j \oplus a_i\)
  • \(a_k \gets a_k \oplus a_i \oplus(a_j \oplus a_i)=a_k \oplus a_j\)

可以看出进行两次操作和只进行后面那一次操作是等价的,即使元素的顺序不同。

那么进行若干次操作后的数组一定和原数组相同或者和只进行一次操作的数组相同,那么把所有的 \(S \oplus a_i\) 插到 std::multiset 里面比较两个 std::multiset 是否相同即可。

G. Nightcrawler

先考虑何时无解,观察样例发现无解的都是连在一起的,而我们要做一个形似树剖的过程,每次剖出的链结尾为叶子,那么当 \(k<s\) 的时候必然无解。其中 \(s\) 为叶子数量。

对于有解的情况,由于我们要最大化最大值的和,从而每次贪心加入当前 \(\max S_i\) 最小的 \(S_i\),这个过程用 \(n\) 个小根堆进行维护,处理到当前节点 \(u\),我们需要启发式合并当前对应的堆,每次合并完与 \(a_u\) 比较,较大的重新丢回去,较小的追加到另外一个全局额外可用的列表里,作为 \(k>s\) 答案的补充量。

由于需要启发式合并,从而这样做是 \(\mathcal O(n \log^2 n)\) 的。

posted @ 2026-08-28 09:27  constexpr_int  阅读(50)  评论(0)    收藏  举报