Codeforces Round 1094 Div.1 做题记录

Codeforces Round 1094 Div.1

编号 CF2222
赛时解决 A,B,C
赛后订题 A,B,C,D

Solution

A

容易发现必须含 \(100\),才能分成 \(1\)

B

容易发现奇数位置和偶数位置是独立分开的,贪心去取即可。

C

我的做法是先用对顶堆做出来每个奇数区间的中位数,这是 \(O(n^2 \log n)\) 的。

然后离散化,令 \(dp[i][j]\) 表示 \(1 \sim i\) 中中位数均为 \(j\) 时的段数,分不了则为 \(-\inf\)

直接 DP 即可,时间复杂度 \(O(n^2 \log n)\)


题解中说这些子区间的中位数一定是整个区间的中位数。

证明考虑每个子区间内大于中位数 \(mid\) 以及小于 \(mid\) 的数的数量是相等的(我们可以把部分 \(=mid\) 看成大于或小于 \(mid\))。

因此总共合在一起就是对的了。

所以求出来整个区间的中位数之后,只需要维护大于和小于 \(mid\) 的个数,递推即可。

时间复杂度 \(O(n^2)\)

D

赛时有思路,但是实现过于复杂(两棵权值线段树),难以解释。

看到逆序对 \((i,j)\) 的贡献为 \(\sum_{k=i}^{j-1} a_k\)很容易想到前缀和的形式,即:

\[\sum_{k=i}^{j-1} a_k = \sum_{k=1}^{j-1} a_k - \sum_{k=1}^{i-1} a_k \]

因此考虑令 \(b_i = \sum_{k=1}^{i-1} a_k\)

那么上式就等价于 \(b_j-b_i\)

考虑一种理想情况,也就是所有 \(b_j - b_i \ge 0\) 的逆序对 \((i,j)\) 都被选上了。

\(i\) 最后的排名为 \(p_i\),那么我们希望:

  • 对于 \(i<j\)\(b_j \ge b_i\),都有 \(p_i < p_j\)
  • 对于 \(i < j\)\(b_j < b_i\),都有 \(p_i > p_j\)

我们发现,\(b,p\) 之间存在相反的关系。我们不妨根据这一点考虑构造:令 \(i\) 按照 \(b_i\) 降序排序,此时 \(i\) 所在的位置即为 \(p_i\)

时间复杂度只有排序的 \(O(n \log n)\)

E

感觉比 D 还简单?赛后独立切了!

简单想一下 \(\text{and,or,xor}\) 的性质,不难想到一种构造方式。见下表。

运算符号 \ \(f(x)\) \ \(x\) \(0\) \(2^n-1\)
\(k = 1 \ \ (\text{and})\) \(0\) \(c\)
\(k=2 \ \\ (\text{or})\) \(c\) \(2^n-1\)
\(k = 3 \ \ (\text{xor})\) \(c\) \(c'\)*

*:其中 \(c' \oplus c = 2^n-1\)\(c \ \& \ c' = 0\)\(c\ |\ c' = 2^n-1\)

\(x = 0\) 的这列,发现 \(f(0)\) 的结果只有 \(0\)\(c\)

这是比较好判断的。我们不妨考虑让 \(0\) 作为集合中的初始元素,然后第一次把 \(f(0)\) 放进去,得到一个返回的集合大小。

显然集合大小 \(=1\)\(k = 1\),否则 \(k = 2/3\)

接下来就可以分讨了。

  • \(k = 1\)
    • \(f(2^n-1) = c\) 加入集合中,并二分查找出 \(c\) 即可。
  • \(k = 2/3\)
    • 此时 \(c\) 就在集合中,直接二分出 \(c\)
    • 接下来需要判断 \(k\) 的值,目前集合中只有 \(\{0,c\}\)
    • 考虑放入一个 \(f(p)\),使得 \(k=2/3\)\(f(p)\) 的值一定不同。
    • 这里我们构造 \(p = 2^w\),其中 \(2^w < c < 2^{w+1}\)。此时若 \(k = 2\) 则集合大小不变。
    • 不过考虑 \(2^w = c\) 的情况,不是很好处理,那干脆直接把 \(f(2^n-1)\) 加入集合(因为本题中 \(n \ge 2\),不会出现 \(2^n-1 = 2^w\))。然后询问集合中 \(\ge 2^n-1\) 的数的个数,如果为 \(1\) 则说明 \(k = 2\),反之 \(k = 3\)

询问次数至多 \(n+3\),复杂度 \(O(Tn)\)

posted @ 2026-07-27 13:50  xiang_you  阅读(8)  评论(0)    收藏  举报