AtCoder Beginner Contest 469 解题报告
前情提要:

愤怒。
将进行一个高效的写题解来,后面忘了。
总之,
ABC469C
我们令前缀 \(i\) 中 hit 出现次数为 \(a_i\),miss 的出现次数的相反数为 \(b_i\)。
考虑 \(k\) 的答案。我们需要求出从 \(k\) 开始,手里有 \(a_k\) 个 hit,最远可以往后走到哪里。不难发现,使 \(a_k + (b_i - b_k) = 0\) 的第一个 \(i\) 便是答案。
如此,我们只需二分找到最后一个 \(j\),使得 \(i \in [k,j]\) 的所有 \(a_k + (b_i - b_k) > 0\),\(\min(j_{\max}+1,n)\) 即为答案。这里,我们可以使用 ST 表快速求 \(b\) 的区间最小值。
ABC469D
假设没有重复的比赛。
考虑 \(i\) 一共在 \(deg_i\) 场比赛中出现。那么我们要统计的,就是满足以下二者之一的数对数量:
-
\(deg_i + deg_j = m + 1\),且 \(i\),\(j\) 之间有过比赛。
-
\(deg_i + deg_j = m\),且 \(i\),\(j\) 之间没有参加比赛。
对于前者,我们对每一场比赛直接判断即可。
对于后者,我们对每个人分别考虑。不考虑「\(i\),\(j\) 之间没有参加比赛」,\(i\) 号选手对应的方案数其实是 \(cnt_{m - deg_i} - [deg_i = m - deg_i]\)。接下来,我们找到所有和 \(i\) 有过比赛的人 \(j\),如果 \(deg_i + deg_j = m\),我们把这种情况从答案中减去即可。
对于后者的计算,我们发现每场比赛会被遍历两遍,所以复杂度正确。
ABC469E
我们让前缀 \(i\) 中 o 出现的次数为 \(b_i\),然后直接二分答案。
然后考虑:胜率 \(x\) 合法,等价于存在 \(0 \le i < j \le n\),使得 \(b_r - b_l \ge k\) 并且 \(\frac{b_r - b_l}{r - l} \ge x\)。后者移项得到 \(b_r - rx \ge b_l - lx\)。那么只需要维护 \(b_i - ix\) 的前缀最小值 \(pre_i\)。对于每一个 \(r\),找到最后一个 \(b_r - b_l \ge k\) 的 \(l\),查询 \(pre_l\) 是否 \(\le b_r - rx\) 即可。这个过程直接用双指针实现。
ABC469F
考虑直接跑 kruskal,然后一共有 \(\mathcal{O}(n ^ 2)\) 条边,但是我们发现,对于一个 \(a \subseteq A\),如果 \(\gcd a = x\),那么里面最多会连上 \(\mathcal{O}(|a|)\) 条权值为 \(x\) 的边。这启示我们从大到小直接枚举边权,对于边权 \(i\),我们需要遍历的元素数量只有 \(i\) 的所有倍数。这样,这是一个调和级数,时间复杂度的下限便来到了 \(\mathcal{O}(V \log V)\)。
继续上面的想法。我们找到 \(i\) 的所有倍数与 \(A\) 的交集 \(S\)。显然我们之前的操作已经把 \(S\) 中的元素连接成了 \(g\) 个块。那么跨块的边权肯定是 \(i\)。如果它是 \(i\) 的倍数 \(ki\),那么肯定已经在遍历到 \(ki\) 的时候被处理完了。那么我们连接 \(g - 1\) 条跨块的边,然后把这些点标记成同一个块即可。我们发现 \(O(|S|)\) 可以完成这些操作,于是时间复杂度取到了上述的下限,问题解决。
ABC469G
我不会。
后续:

有个角色敢 8 点血打实验体,你知道它是谁。

浙公网安备 33010602011771号