Codeforces Round 1112 Div.2 做题记录
Codeforces Round 1112 Div.2
| 编号 | CF2250 & 2249 |
|---|---|
| 赛时解决 | A,B,C |
| 赛后订题 | A,B,C,D |
Solution
A
【+10min】
有点诈骗。
想要 Yes 的话,\(1 \sim n\) 位置上的数都要移动,而移动后还要在这些位置。
所以 \(1\) 只能移到 \(2\),同理 \(2\) 只能移到 \(1\),\(3\) 只能移到 \(4\) 等。即 \(2k-1\) 与 \(2k\) 互换。
所以如果 \(n\) 为奇数,那直接是 No。
如果有解,那么我们就需要找到一个 \(k\),满足所有奇数位置上的元素都 \(> k\),所有偶数位置上的元素都 \(< k\)。
那么统计奇数位置s行的最小值,和偶数位置上的最大值,并确定这两个值之间是否有值(即这两个值的差是否 \(> 2\) )即可。
B
【+2min】
注意到 \(0,1\) 互换对有解序列没有影响。
【+3min】
因此发现 \(0,1\) 的数量可以是确定的。
【+10min】
考虑增量构造。
先排成 \(0000\dots111\) 的形式,其中 \(0\) 的个数不少于 \(1\) 的个数。
初始答案是上界 \(n-2\),然后考虑以下两种操作:
- 把最后的 \(1\) 插到最靠前的连续两个 \(0\) 之间,答案会减少 \(2\)。
- 把最后的 \(0\) 放到最后,答案会减少 \(1\)。
于是一直用 \(-2\),最后看要不要来一个 \(-1\) 即可。
C
【+6min】
\(n \le 5000\),考虑 \(n^2\) 做法。
【+10min】
考虑枚举 \(m\),然后会发现从小到大尽可能的选 \(i\),就没有后效性了。
所以枚举 \(m\),能选就选即可。
D
好题。
【+10min】
首先思考 \(n\) 的位置,由于排列,所以 \(\min\) 里的两个 \(\max\) 一定会一个取到 \(n\),另一个 \(< n\),所以 \(v_i < n\)。
因此如果 \(\forall v_i = n\),直接为 \(0\),判掉。
【+15min】
考虑 \(n\) 在排列中的哪个位置。
注意到在 \(n\) 左侧,\(v_i\) 会随 \(i\) 的增大而不降,这是因为第二个 \(\max = n\),而第一个 \(\max\) 的范围是扩大的。
同理,在 \(n\) 右侧,\(v_i\) 会随 \(i\) 的增大而不增。
所以一个合法的序列一定存在至少一个分割点 \(c\),满足 \(\forall 1 \le i < c\),\(v_i\) 单调不降;\(\forall c \le i < n\),\(v_i\) 单调不增。
又因为 \(c\) 左右两边不可能同时出现同一个数字,即不存在 \(i < c < j\) 使得 \(v_i = v_j\),这样就必须 \(n\) 左右各有一个 \(v_i\),与排列矛盾。
因此,分割点合法的前提条件是 \(a_{c-1} \neq a_c\)。所以合法的 \(c\) 至多 \(2\) 个。
【+20min】
考虑确定了 \(c\) 要怎么来做。
现在我们知道另一个 \(\max\),也就是 \(v_i\) 是从哪边取到的了。
于是问题就变成了:有多少种方案,使得 \(v_i = \max_{1\le j \le i} p_j\) 或 \(v_i = \max_{i\le j \le n}\)。
考虑把 \(c\) 左右两边的有序序列归并起来,复杂度是线性的。
在归并的过程中,可以判断是否存在 \(i < c < j\) 使得 \(v_i = v_j\) 的无解情况。
然后考虑在合并后的序列上做。对于第一次出现的 \(v_i\),那么它对应的位置(如果在 \(c\) 左边对应的位置就在它左边,反之在右边)上一定填 \(v_i\)。否则,可以填任意一个不超过 \(v_i\) 且未被填写的数。
由于合并后的有序性,所以很容易算出来还没被填且不超过 \(v_i\) 的数的个数,这些数都可以填,答案乘上这些数的个数。
如果没数可填,无解。
于是就做完了,时间复杂度线性。

浙公网安备 33010602011771号