CF2026
A
题意
有 \(n\) 个灯和 \(2 \times n\) 个开关,每个灯都由两个开关控制,不知道电路,但知道开关的开闭,问最小亮灯数量和最大亮灯数量。
分析
最小:让开着的开关的两两抵消。
最大:开着的开关先开满,如果还有,剩余的和之前开的两两抵消。注意到抵消完还开着的灯数量等于关着的开关数量。
B
题意
给一个数组 \(a=[1,2, \dotsb ,n]\)(保证 \(n\) 为奇数),需要将这个数组划分成连续的 \(m\) 段(\(m\) 不固定),使得
- 每段的长度都是奇数;
每一段的中位数
的中位数等于给定的 \(k\)。
构造一个划分方案。
分析
注意到条件二的关键只在最中间一段,我们可以让中间的一段只包含 \(k\) 一个元素以满足条件二。剩下的工作就是让左边的段数为奇数,右边的段数也为奇数,且左右划分出的段数相等。
接下来只要对左边右边根据奇偶性分类下就行,若左右奇偶性不相同则无解。全奇数整个作为一段即可,全偶数先分出一个再整个作为一段即可。
还有一些总数较小的边界情况,讨论下也不难。
C
题意
给一个数组 \(a\),每次可以任选 \((i,j)\) 将 \(a_i\) 赋值为 \(a_j\)。问满足下述条件的最小操作次数。
- 对每一个没有相同元素的三元组 \((i,j,k)\),\(a_i,a_j,a_k\) 作为一个三角形的三条边是合法的。
分析
排个序,注意到最容易不合法的地方是 \((1,2,n)\) 组合,如果这个组合合法,那整体肯定合法。
那我们有两种选择:把最小值改大、把最大值改小。
怎么选?我们不妨枚举选了几个把最大值改小。由于我们的更改肯定会一步到位,那改成了什么其实已经无所谓了,反正肯定只花费了一步。
枚举把几个最大值改小之后,可以直接二分出最小值改到了哪里恰好合法。注意到二分出的位置是单调递减的,所以双指针也行。
D
题意
交互题,有一棵 \(n\) 个点的树,编号从 \(0\) 到 \(n-1\),不知道形态,但已知以下性质:
- 如果删除节点 \(0\),则树会变成一组链。
- 记 \(p_x\) 表示 \(x\) 节点的父亲,若 \(1 \le x \le y \le n-1\),则 \(p_x \le p_y\)。
- 节点 \(1\) 的度数为 \(2\),且节点 \(0\) 与节点 \(1\) 相连。
每次询问两个点,交互库返回这两个点之间的简单路径是否包含节点 \(0\)。询问次数不能超过 \(2 \times n-6\)
还原树的最终形态。
分析
\(1\) 号点被强调了特殊性质,我们从 \(1\) 号点入手。
首先依次询问 \((1,2),(1,3), \dotsb ,(1,t)\) 直到答案为 \(1\),可以确定这个 \(t\) 就是 \(1\) 的儿子,且 \([2,t-1]\) 的父亲都是 \(0\),这利用了性质二。
之后的点只需要维护一个指针指向当前测试的父亲节点,双指针移动分别确定即可。
第一部分询问次数为 \(t-2 \le n-3\),第二部分最坏情况指针从 \(2\) 移动到 \(n-2\),询问次数为 \(n-3\),加起来是 \(n-6\),正好满足题目要求。
E
题意
给一个环形数组 \(a\),你可以进行任意次操作,每次操作形如:
- 选一个位置 \(i\),\(a_{i-1}\) 增加 \(1\),\(a_i\) 增加 \(2\),\(a_{i+1}\) 增加 \(1\)。
构造一个操作方案,使得 \(a\) 的每个位置都相等。
分析
是官方解法。
我们不妨允许“负操作”:选择一个 \(i\),将 \(a_{i-1}\) 增加 \(-1\),\(a_i\) 增加 \(-2\),以及 \(a_{i+1}\) 增加 \(-1\)。如果最终在数组 \(v\) 中出现负元素,我们可以通过将所有 \(v_i\) 同时增加,从而使最终数组 \(v\) 合法,不难发现这并不影响差分数组。
考虑 \(n=3\) 的情况。让 \(a_1=a_3\) 相等是容易的,只需要对小的那个进行差值次操作即可,最后在 \(a_2\) 上进行一些操作让三者平衡。对任意 \(n=3\) 这种解法都是正确的。
我们发现这种操作其实是让原数组有了对称性,接下来我们尝试把这种做法扩展到一般的情况下。
\(n>3\) 怎么说?让 \(a_1=a_n\) 可以用上面的第一步,但是让 \(a_2=a_{n-1}\) 要花点心思。牢记我们的目标:让这两个位置的增量产生差值填补现有的差值。
拿官方题解 \(a=[48,18,26,57,39]\) 的例子。
- 首先,我们平衡 \(a_1\) 和 \(a_5\)。只需对 \(a_5\) 进行 \(9\) 次操作。数组变为 \([57,18,26,66,57]\)。
- 然后,我们平衡 \(a_2\) 和 \(a_4\)。我们从 \(a_2\) 开始,每次向左移动两个(在循环意义下),直到到达 \(a_5\),每次移动到一个位置就操作 \(48\) 次。也就是说对 \(a_2\) 和 \(a_5\) 各操作 \(48\) 次。数组变为:\([153, 114, 64, 114, 153]\)。
至此数组有了良好的对称性。
一般地,想要平衡 \(a_i\) 和 \(a_{n-i+1}\),我们的操作指针需要从 \(i\) 开始每次向前移动两个,直到到达 \(a_{n-i+2}\),操作的次数就是 \(|a_i - a_{n-i+1}|\)。
接下来考虑第二步,回到例子,最中间的一个容易与两边平衡,数组变为 \([153,164,164,164,153]\)。
接下来对 \(a_2\) 和 \(a_4\) 操作 \(-11\) 次就行,数组变为 \([142,142,142,142,142]\)。随便手玩下就能发现这是对目前已经平衡的中间一段隔一个操作一次。
至此操作结束。考虑如何统计每个位置的操作次数。第一步是一段前缀和一段后缀操作,注意到路径上奇偶性不变,那可以奇数位置和偶数位置分开做前缀和,操作次数就是差值。第二步同理。
别忘了把负的操作数加成非负的。