+++ date = "2021-11-13T01:50:00+08:00" draft = false tags = [] title = "Codeforces Round #754 (Div. 2)" authors = ["xry111"] +++ * [比赛链接](https://codeforces.com/contest/1605) # [A - A.M. Deviation](https://codeforces.com/contest/1605/problem/A) 题意:给你三个数 $a\_1, a\_2, a\_3$, 每次你可以给 $a\_i$ 加 $1$,$a\_j$ 减 $1$。 要求最小化 $$d(a\_1, a\_2, a\_3) = |a\_1 + a\_3 - 2 \cdot a\_2|$$ 显然,在题目给定的条件下,只要保证三个数和不变,可以随便改变它们的值。 最优解显然是使得三个数尽量接近,那就取它们的平均值向上向下取一取整就行了。 试几个数会发现如果 $\\sum a\_i$ 是 $3$ 的倍数则可以使得 $d$ 为 $0$, 否则 $d$ 为 $1$。 用 Python 3 可以写很短: ```python t = int(input()) for cs in range(1, t + 1): a = sum(map(int, input().split())) print(int(a % 3 != 0)) ``` # [B - Reverse Sort](https://codeforces.com/contest/1605/problem/B) 题意:给你一个串 $s \\in \\{0, 1\\}^\*$,每次操作可以从中选一个子序列, 然后将其反序,要求用尽量少的操作将整个串排好序。 这题初看上去很不可做,但是一看串只有 $0$ 和 $1$,再一看样例要么操作 $1$ 1 次要么操作 $0$ 次就感觉是假题…… 然后发现只要把 $s$ 排个序得到 $t$ 以后, 找到所有 $s[i] \neq t[i]$ 的位置做反序就行了。 这题用 Python 3 也可以写很短,但是场上把数据范围看成了 $1000 \times 1000$ 就怕卡常没敢用 Python,赛后才发现数据范围就是 $1000$。 # [D - Treelabeling](https://codeforces.com/contest/1605/problem/D) 由于 C 题看上去很不可做,于是先去写 D。 题意:给一个树 $T = (V, E)$,你可以指定一个双射 $f: V \\rightarrow \\{1, 2, \cdots, |V|\\}$。如果 $(i, j) \\in E$,且 $f(i) \\oplus f(j) > \\min(f(i), f(j))$,就把 $(i, j)$ 这条边删掉,这样会得到一个森林 $G = (V, E')$。 然后你选一个点 $v\_0$ 放一个棋子。之后你的对手先手,两人轮流移动, 每次可以将棋子沿 $E'$ 中的一条边进行移动,不能移动到棋子曾经占据过的点, 如果某人无法移动则输。要求你求出一个 $f$,使得能选做 $v\_0$ 的点尽量多。 这题初看上去很不可做,但是 “你的对手先手” 这个条件就很有趣。 然后在纸上画了画,感觉能够构造 $f$ 将所有边删光, 自闭了一会以后就想到怎么构造了:首先 $T$ 作为树一定是二分图。 那么我们对它做一个黑白染色,一定有一种颜色的点 (不妨设是黑点) 的个数 $c$ 不超过 $\\lfloor n / 2 \\rfloor$。然后我们发现若 $a > 0$ 且 $b > 0$,则 $a \\oplus b > \\min(f(i), f(j))$ 的一个充分条件是 $$\\text{highbit}(a) \\neq \\text{highbit}(b)$$ 其中 $\\text{highbit}(x)$ 是 $x$ 中最高的,为 $1$ 的二进制位。 于是我们把 $S = \\{1, 2, \cdots, |V|\\}$ 按照 $\\text{highbit}$ 值做一个划分: $$S\_0 = \\{ 1 \\}$$ $$S\_1 = \\{ 2, 3 \\}$$ $$S\_2 = \\{ 4, 5, 6, 7 \\}$$ $$\\cdots$$ $$S\_m = \\{ \\cdots, |V| \\}$$ 这样如果 $i \\neq j$ 且 $u \\in S\_i$, $v \\in S\_j$, 则边一定会被删掉, 即 $(u, v) \notin E'$。 显然,对于 $k < m$,$|S\_k| = 2^k$, 且 $$\\sum\_{k < m} |S\_k| = 2^{\\lfloor \\log\_2 |V| \\rfloor} - 1 \\geq \\lfloor n / 2 \\rfloor \geq c$$ 因此我们可以把黑点的个数 $c$ 表示成 $m$ 位二进制: $$c = \\sum\_{i = 0}^{m - 1} 2^i x\_i$$ 然后如果 $x\_i = 1$,我们就将 $S\_i$ 中的元素都分配给黑点, 这样一定能为所有黑点都分配一个 $f(\\cdot)$ 值。 之后将 $S$ 中尚未分配的元素都分配给白点。这样,就不存在 $(u, v, k)$ 使得 $u$ 与 $v$ 异色,且 $u, v \\in S\_k$。这就保证了 $E' = \\emptyset$。 此时根本没有边,对手一步都动不了,所有点都可以作为 $v\_0$。 # [C - Dominant Character](https://codeforces.com/contest/1605/problem/C) 题意:给定串 $s \\in \\{a, b, c\\}^\*$,要求你在 $s$ 中找一个尽量短的子串 $t$,使得 $|t| \geq 2$,$t$ 中 $a$ 的个数大于 $b$ 的个数,也大于 $c$ 的个数。 这题一开始以为是树套树二维偏序,然而做了 A、B、D 以后就感觉这出题人只会出假题,所以这题肯定也是假题。 然后就猜想如果 $|t| > 10$,就存在 $t'$ 是 $t$ 的真子串, 且 $t'$ 也满足条件,所以假设 $|t| \leq 10$ 然后交了一下就过了。 至于为啥我暂时蒙在鼓里 …… 而且我很讨厌这种 “暴力加个 `break` 就能过” 的假题,因为我认为这会鼓励乱冲暴力的壬。