CF671E

首先可以想到尝试使用扫描线,只需对每个 \(r\) 求出最优的 \(l\) 即可。

先假设没有 \(k\) 次修改机会。考虑令 \(a_i = g_i - w_i, b_i = g_i - w_{i - 1}\),即向右 / 向左走时经过点 \(i\) 油量的增量。

\(a, b\) 的前缀和分别为 \(S_i, T_i\),于是有:

\[\begin{aligned} \forall i \in [l, r - 1], \sum_{j = l}^{i} a_j \ge 0 &\iff S_{i} \ge S_{l - 1} \\ \forall i \in [l + 1, r], \sum_{j = i}^{r} b_j \ge 0 &\iff T_{i - 1} \le T_{r} \end{aligned} \]

第二个条件即 \(\forall i \in [l, r - 1], T_i \le T_r\)

现在我们考虑修改。显然最优的修改方案是把所有 \(k\) 次都用在 \([l, r]\) 区间内。考虑将 \(g_i + 1\) 带来的变化,即 \(S, T\) 数组后缀 \([i, n]\)\(1\)。于是我们要求的就是对每个 \(r\),进行 \(k\) 次这样的后缀加后能得到的最远的 \(l\)

\(r\) 左侧第一个 \(T_i \gt T_r\)\(i\)\(lef_r\),则根据第二个限制,\(l \in (lef_r, r]\),显然我们为了让 \(l\) 更远需要贪心地使 \(lef_r\) 左移,而对于一个 \(lef_r\),左移的代价是 \(T_{lef_r} - T_r\) 次操作(这些操作只需满足 \(i \in (lef_r, r]\) 即可)。注意到进行这些操作后 \(T_r\) 就变成了原本的 \(T_{lef_r}\),以此类推,我们可以得出最远能扩展到的 \(lef_r\) 是最小的 \(i\),使得 \(T_i - T_{r} \le k\)。可以看出我们扩展的过程相当于单调栈弹栈的过程,所以直接在 \(r\) 处的单调栈上二分即可。

再考虑第一个限制,假设 \(r\) 处的单调栈为 \(sta_1, sta_2, \dotsb, sta_{k}\),其中 \(sta_k = r\),假如答案 \(l\)\([sta_i + 1, sta_{i + 1}]\) 区间里,则 \(S_{l - 1}\) 需满足 \(S_{l - 1} = \min_\limits{j = l - 1}^{r - 1} S_j\),那么显然之前将 \(lef_r\) 向左扩展直到 \(sta_i\) 的所有操作都可以贪心地向左放(因为这样可以保证 \([l, r - 1]\)\(S\) 增加得更多),也就是说,\(lef_r\)\(sta_{j + 1}\) 扩展到 \(sta_{j}\) 的时候,我们可以将 \(T_{sta_{j}} - T_{sta_{j + 1}}\) 次操作都放在 \(sta_{j} + 1\) 处完成。

但是 \(S\) 的这些后缀加不好维护(需要一边扩展 \(lef_r\) 一边进行这些修改),所以我们考虑把 \(S\) 数组 \([i, n]\) 的后缀加 1 变成 \([1, i - 1]\) 的前缀减 1。注意到这样对于 \(sta_{1 \sim i - 1}\),其对前缀的改变就不会影响到我们判定 \(S_{l - 1} = \min_\limits{j = l - 1}^{r - 1} S_j\) 了(可以画个图手搓一下这部分,可能比较难理解)。于是前一段提到的贪心策略变成了每次将前缀 \([1, sta_{j}]\) 减去 \(T_{sta_j} - T_{sta_{j - 1}}\)

注意到我们可以在维护 \(r\) 处的单调栈的同时进行这些修改,每次向栈里插入一个元素就进行上述前缀减,弹出则取消这部分贡献即可。用线段树维护进行这些修改后的 \(S\) 数组,记为 \(S_0\)

接下来考虑怎么求 \(l\),假设 \(l \in [sta_i + 1, sta_{i + 1}]\),将 \(lef_r\) 扩展到 \(sta_{i}\) 后剩下了 \(k_0\) 次操作,那么显然最优的方案是对 \([1, l - 1]\) 进行 \(k_0\) 次前缀减,注意到此时 \(S_{l - 1}\) 一定是被减了恰好 \(k\),所以只需判断 \(S_{0}[l - 1] = S_{l - 1} - k \le \min_\limits{j = l}^{r - 1} S_0[j]\) 即可。

形式化地,我们需要维护一个数组 \(S_0\),再给定一个数组 \(S\),支持 \(S_0\) 前缀加、查询最小的满足 \(-S_{l - 1} + \min_\limits{j = l}^{r - 1} S_0[j] \ge -k\)\(l\)。于是这就转化成了单侧递归线段树能维护的模型。

代码咕了.jpg

posted @ 2026-01-10 23:03  Neutral1sed  阅读(63)  评论(0)    收藏  举报