Codeforces Round 1093 Div.1 做题记录
Codeforces Round 1093 Div.1
| 编号 | CF2219 |
|---|---|
| 赛时解决 | A,B1 |
| 赛后订题 | A,B1,B2,C |
| rank | 705 |
Solution
A
横杠和拐角分别有 \(p,q\) 个时,我们先考虑把拐角掰成两半,这样一共有 \(p+2q\) 个横杠。
那么最后的 \(n,m\) 必须满足 \(n(m+1)+m(n+1) = p+2q\)。
因此我们发现令 \(n \le m\) 的话 \(n\) 不会很大,也就是差不多 \(2000\) 左右就最大了。
考虑枚举 \(n\) 与此同时得到 \(m\)。手玩一下不难发现横杠的个数 \(p\) 不能少于 \(|n-m|\),判一下即可。
B1
思想:二进制分组,差量法。
赛时神秘思路。
首先观察到如果我们两次询问分别问 \(S\) 和它的补集 \(T\) 的话,那么只有当三个相同的数(记为 \(x\))都在同一个集合里时,\(ask(S) = ask(T)\),否则更多的那一边有 \(1\) 个。
考虑二进制分组,因为这样一定会存在两种情况(三个数至少存在两个二进制位不同)能得到哪边有一个。询问次数 \(2 \log_2 (n+1) = 22\) 次。
得到 \(1\) 个所在的集合之后,就可以在这个集合内二分出位置。按照这种方法可以得到两个位置上的数,此时总询问次数达到了 \(66\) 次。
不过第三个位置可以直接根据二进制分组的不同,判定它和第一个位置所在的二进制位是否相同,从而直接被还原出来。因此这样可以通过。
B2
转换思考角度,发现只有 \(S\) 中有 \(3\) 个相同的数字时,\(ask(S)\) 与 \(|S|\) 的奇偶性不同。
证明显然。考虑用这一性质在 \(\log_2(n+1) = 11\) 次二分找到最后一个出现 \(3\) 次的数的位置。
然后我们把这个数固定地放到集合 \(S\) 中,并在它前面二分找到第二个位置。第一个位置寻找同理。
总的询问次数 \(3 \times 11 = 33\)。
C
有一个很不错的思路,如果两个黑点之间隔的有红点,那么它们是没法相互影响的。
因此考虑按照红点拆分出来一些小的树,使得:
- 这些树的根都是黑点。
- 红点只可能在叶子上。
具体实现并不需要拆边,而是从根开始深搜,搜到红点就停即可。
根据期望的线性可加性,最后的答案就是每棵小树的答案之和。
还有一个前置知识,如果一个事件一次发生的概率为 \(\frac{1}{p}\),那么这个时间发生的期望次数为 \(p\)。
然后在这些树上去做 DP,没法从父亲转移,那就假设父亲的颜色!
设 \(dp[u][0/1]\) 表示以 \(u\) 为根的子树全部为红色,且 \(u\) 比父亲先或后(\(0\) 或 \(1\))变红时,最小的期望操作次数。也就是说,\(0/1\) 分别代表了 \(u\) 变红时父亲的颜色是黑色还是红色。
那么对于叶子节点有初始值:
- 若 \(u\) 为红色:\(dp[u][0] = 0, dp[u][1] = \text{inf}\)。
- 否则:\(dp[u][0] = \inf, dp[u][1] = 1\)(只需一步一定变红)。
转移,记 \(u\) 的子节点个数为 \(m\),其中有 \(k\) 个红点。并且红点集合和黑点集合分别为 \(S,T\),那么:
以及:
以计算 \(dp[u][0]\) 为例,改写这个 DP 式子:
此时 \(\sum_v dp[v][0]\) 为定值,那么随着 \(k\) 的减少(即集合 \(T\) 的扩大),我们希望贪心地优先选择 \(dp[v][0] - dp[v][1]\) 更大的值加入。
因此按 \(dp[v][0] - dp[v][1]\) 先排一遍序就好。不要忘了 \(T\) 为空也是可以的。

浙公网安备 33010602011771号