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)\) 的。
本文来自博客园,作者:Trent900,转载请注明原文链接:https://www.cnblogs.com/GE9X/p/21640323

浙公网安备 33010602011771号