CF1628 Codeforces Round #767 (Div. 1) 题解(C-E)
比赛总结
- 整体打得是最近 10 场最煎熬的一场,但是没有摆烂,相较于以前有进步。
- A 太慢了,有一个地方的想复杂了,其实暴力是对的
- B 也没有想清楚,开始的时候想到了 23 可以,然后分类讨论了一会儿就以为是 223 才行,其实 23 就可以替代 223 的情况了,于是贡献了 5 发罚时(其中有一发是手抖了),直接使得 B 的分数几乎是 A 的分数的一半。
- C 列出了方案,但是最后计算贡献的时候画错了图,于是把方案叉掉了,根本不会。
- D1 写出来了,但是有一个比较明显的结论(单调性)没有注意,于是 D2 也不会。
- 前面太烂了,E 根本没看,不然就是一个 Kruskal + 线段树的裸题,应该可以切,就可以将下分场化为上分场。
题解
整场比赛的代码可以在 CF/contest/1628 · yinjinrun/code-public-2 - 码云 - 开源中国 (gitee.com) 中查看。
CF1628C Grid Xor
给出一个网格图,每个位置有值 \(a_{i, j}\) 表示与其相邻的所有网格的 \(b_{i, j}\) 的 xor 和(不包括该位置)。
求出整个网格图的 xor 和。
构造
比赛的时候想到了构造方式,然后实际构造的时候,中间的格子只画了上半部分,画错图了,然后就以为是不对的。
于是自闭了。
然后可以这样子:从上到下依次考虑每个格子,如果一个格子上面的格子被 xor 的贡献是 \(0\),那么对该格子进行一次操作。
画图可以证明是对的(
CF1628D2 Game on Sum (Hard Version)
Alice 和 Bob 正在玩游戏,共有 \(n\) 轮,每轮 Alice 可以选择一个实数 \(x \in [1, n]\),然后 Bob 可以选择将分数加上 \(x\) 或者使得分数减去 \(x\),并且 Bob 必须选择 \(m\) 次加法操作,Alice 要让分数最大,Bob 要让分数最小,假设两人绝顶聪明,问最后的分数的是什么。
\(n, m \le 10^6, k < 10^9+7\)
Easy Version: \(n, m \le 2000\)
动态规划
数学
考虑 easy version 的一种比较暴力的解法:
- 设 \(f_{i, j}\) 表示还有 \(i\) 轮,至少有 \(j\) 轮要加的答案(可以同时维护实数取值(方便比较大小)和取模意义下的取值)
- 显然,当 \(i = j\) 的时候,\(f_{i, j} = ik\)(因为必须加),当 \(j = 0\) 的时候,\(f_{i, j} = 0\)(必须减)。
- 然后其他情况,就可以考虑设 \(a = f_{i - 1, j - 1},b = f_{i - 1, j}\),\(a\) 代表加法,\(b\) 代表减法。如果 \(a > b\),那么无论如何,Bob 都会选择减法,于是 \(f_{i, j} = b\),如果 \(a \le b\),设选择的数字是 \(x\),那么 \(f_{i, j} = \min\{a + x, b - x\}\),Alice 为了分数更优,于是让 \(f_{i, j} = \frac{a + b}{2}\)
以上使我赛时想法,然后脑抽了,上面这个形式一直不会优化,其实我们发现有 \(1\) 个地方是没用的:
\(a \le b\),\(f_{i}\) 显然单调。
于是 \(f_{i, j} = \dfrac{f_{i - 1, j - 1} + f_{i - 1,j}}{2}\),那么 easy version 就是一个简单的 DP 了。
现在考虑 hard version,因为 \(i = j\) 的时候答案就是 \(ik\),于是我们可以对于每个 \(i\) 计算贡献。
对于 \(f_{i, i}\),考虑一张网格图,每次可以 \((i, j) \to (i + 1, j)\) 或者 \((i, j) \to (i + 1, j + 1)\),那么最后 \(f_{i, i}\) 对于 \(f_{n, m}\) 的贡献就是 \((i, i)\) 走到 \((n, m)\) 的方案数 \(\times\) \(\dfrac{ik}{2 ^ {n - i}}\)。
于是可以考虑所有 \(i \le m\),然后计算贡献就行了!
但是有个小问题,我们规定了走到 \((i, i)\) 就停止计算贡献了,但是可能会从 \((i, i)\) 走到 \((i + 1, i + 1)\),然后贡献就算重了,为了解决这个问题,我们可以钦定第一步是 \((i, i) \to (i + 1, i)\),这样贡献就不会算重了。
CF1628E Groceries in Meteor Town
Mihai lives in a town where meteor storms are a common problem. It's annoying, because Mihai has to buy groceries sometimes, and getting hit by meteors isn't fun. Therefore, we ask you to find the most dangerous way to buy groceries so that we can trick him to go there.
The town has \(n\) buildings numbered from \(1\) to \(n\). Some buildings have roads between them, and there is exactly \(1\) simple path from any building to any other building. Each road has a certain meteor danger level. The buildings all have grocery stores, but Mihai only cares about the open ones, of course. Initially, all the grocery stores are closed.You are given \(q\) queries of three types:
- Given the integers \(l\) and \(r\), the buildings numbered from \(l\) to \(r\) open their grocery stores (nothing happens to buildings in the range that already have an open grocery store).
- Given the integers \(l\) and \(r\), the buildings numbered from \(l\) to \(r\) close their grocery stores (nothing happens to buildings in the range that didn't have an open grocery store).
- Given the integer \(x\), find the maximum meteor danger level on the simple path from \(x\) to any open grocery store, or \(-1\) if there is no edge on any simple path to an open store.
\(2 \le n, q \le 3\cdot 10^5\)
数据结构
Kruskal 重构树
什么鬼,CF div1 的 E 是 Kruskal 重构树 + 线段树的板子?
比赛后悔没看 E。
F
咕咕咕咕