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\) 的数的个数,这些数都可以填,答案乘上这些数的个数。

如果没数可填,无解。

于是就做完了,时间复杂度线性。

posted @ 2026-07-29 11:33  xiang_you  阅读(24)  评论(2)    收藏  举报