AtCoder Beginner Contest 467 补题

A - Obesity

注意不要用浮点数。

B - Keep the Change

如果 $s_i = $keep,那么答案累加 \(b_i - a_i\) 即可。

C & E - Adjacent Sums

我们令 \(a_i\) 被操作的次数为 \(x_i\)

考虑简单版本(\(m = 2\))。

不难发现,一旦 \(x_i\) 被确定,那么剩下点的最小取值也都被确定了。

我们直接枚举 \(x_i\) 即可,对数组进行两次遍历就好了。

接着,考虑困难版本(\(m \le 10^9\))。

同样地,因为我们有 \(0 \le x_i < m\),那么其实所有的数也是可以直接通过 \(x_1\) 确定的。

那么,整个代价就变成了一个关于 \(x_1\) 的函数了,我们要求的是这个函数的最小值。

我们令 \(c_i = (b_i - (a_i + a_{i + 1})) \mod m\),那么我们有 \(c_i = (x_i + x_{i + 1}) \mod m\)

于是 \(x_{i + 1} = (c_i - x_i) \mod m\)

我们令刚刚提到的函数为 \(f\),那么 \(f(x) = \sum_{i = 1}^{n} x_i\),我们观察 \(x_i\) 的规律(模 \(m\) 意义下):

  • \(x_1 = t\)

  • \(x_2 = c_1 - t\)

  • \(x_3 = c_2 - c_1 + t\)

  • \(x_4 = c_3 - c_2 + c_1 - t\)

所以,我们发现 \(x_i = \pm t + c 的交替和\)。在 \(t\)\([0,m)\) 上的变化中,每个 \(x_i\) 都会出现一次因为模 \(m\) 而骤增/骤降的情况,我们只需要计算这些点附近,可能为最小值的 \(f\) 值即可。

那找到这 \(n\) 个点之后,如何快速计算此时的 \(f\) 值呢?

我们先找到所有的询问点,然后排序。这样,函数发生的每一次突变带来的变化量,我们就可以前缀和统计了。最后加上初始值就好了。

D - Concentric Circles

这是一道简单的几何题。题目给出的东西等价于两条线段。我们只需要判断这两条线段是否有公共点即可,即是否【不平行或重合】。

F - Email Scheduling Optimization

这个一眼看上去确定大体思路:确定贪心策略,数据结构维护。

我们不难想到,尝试邻项交换法。

如果 \(i\)\(j\) 交换后不劣,则有 \(\max(a_i + a_j + b_j, a_i + b_i) > \max(a_j + a_i + b_i, a_j + b_j)\)

不难发现直接将 \(b_i > b_j\) 代进去就是对的,这里讲讲咋推。

首先,处理 \(\max(a,b) < \max(c,d)\) 式,我们可以尝试将式子等价为 \(a < \max(c,d)\)\(b < \max(c,d)\)。于是我们有:

  • \(a_j + b_j < \max(a_i + a_j + b_j, a_i + b_i)\)。不难发现这个恒成立。

  • \(a_j + a_i + b_i < \max(a_i + a_j + b_j, a_i + b_i)\)\(\mathrm{LHS}\) 一定大于右边第二项,所以 \(a_j + a_i + b_i < a_i + a_j + b_j\),即 \(b_i < b_j\)

所以我们得到 \(b_i < b_j\) 时,交换 \(i\)\(j\) 一定更优。

于是按照 \(b\) 为关键字排序,我们可以计算出最终结果。

维护是简单的,使用平衡树或者线段树均可。

G - Many Sweets Problem

这个其实很模板。考虑,如果这个查询是静态的,那么我们可以在线段树上套 vector,存储每个节点代表的区间里面的所有数,然后二分最小值。

但是这题带修,于是我们可以树套树,具体地,在外层的权值线段树上套内层的树,内层维护表达在某一个范围的数在哪些位置出现,以及它们贡献的区间和,查询直接在外层的线段树上二分糖的最小值即可,可以顺便统计吃了多少糖。

修改和查询均是 \(\mathcal{O}(\log ^ 2 n)\) 的。

posted @ 2026-07-19 11:33  Trent900  阅读(34)  评论(1)    收藏  举报