「IOI 2021」分糖果(线段树)

传送门

分析:

离线后对序列做扫描线。相当于扫到 (l)(r + 1) 时,添加或删除一个 (t) 时刻的操作。开个数组 (a),把 (t) 时刻对糖果数量的修改量记在 (a_t) 上,我们要支持 (a) 的单点修改,以及对于容量为 (c) 的糖果盒的询问。

有两边的限制看着不好做,考虑先去掉下界限制。发现一定有一个时刻减到 (0),之后不再减到 (0)。记 (f(c)) 为容量 (c) 的答案,记 (g(c, i)) 表示只考虑 (a_i) 开始的后缀,且可以扣到负数时的答案,那么 (f(c) = max(g(c, i)))

(a) 的后缀和为 (s),那 (g(infty, i)) 就是 (s_i)。而 (g(c, i)) 还要减去 (i) 开始的最大前缀和超过 (c) 的部分,也就是 (max(0, s_i - s_j - c))。因此 (g(c, i) = min(s_i, min s_j + c))(j ge i))。

我们要求 (max g(c, i))。发现只有 (s_i) 为后缀最大值时有用。记 (x, y) 分别为 (s) 的后缀 max 和 min,我们求的就是 (max(min(x_i, y_i + c)))。搞个线段树二分,分段做即可。时间 (O(n log n))

提交记录

原文地址:https://www.cnblogs.com/Alfalfa-w/p/15162597.html