题解:AT_arc187_d [ARC187D] Many Easy Optimizations

Cat_Mouse

2024-11-18 15:08:23

Solution

前言

场上调 DS 调不出来。/hsh

这篇题解使用吉司机线段树,不是正解的 set 维护。

题意描述

给两个长为 n 的序列 a,b,序列 c 满足 \forall i\in[1,n],c_i=a_i \operatorname{or} c_i=b_i

对于 i=1\dots n 分别求 c_{1\sim i} 的极差的最小值,极差即 \max\limits_{j\le i}c_j-\min\limits_{j\le i}c_j

### 解法 先令 $a_i\le b_i$($a_i>b_i$ 则交换),这样对答案不影响。 从小到大枚举 $2n$ 个可能的最小值,设当前最小值为 $mn$。 限制就是 $c_i\ge mn$,可以贪心。 - $a_i\ge mn$,选择 $c_i=a_i$ 一定比 $c_i=b_i$ 优。 - $b_i\ge mn>a_i$,只能选择 $c_i=b_i$。 - $mn>b_i$,选不了,只能更新 $k<i$ 的答案。 用一个指针维护最大的 $k$ 使得 $\forall j\le k,b_j\ge mn$,$mn$ 只更新 $1\sim k$ 的答案,就不会第三种情况。 由于从小到大枚举 $mn$,对于某个 $c_i$,一开始 $c_i=a_i$,在某个时刻 $mn>a_i$,这时候 $c_i\gets b_i$。 可以指针扫一遍维护出来到 $mn$ 时更新的 $c_i\gets b_i$。 知道了最小值,需要最大值 $\max\limits_{j\le i} c_i$ 更新答案。 于是暴力 $O(n^2)$ 就是 $i\le k$ 的点的答案用 $\max\limits_{j\le i} c_i-mn$ 更新。 直接维护出 $c$ 的前缀 max 数组 $d$,$d_i=\max\limits_{j\le i} c_i$,用 $d_i-mn$ 更新 $i$ 的答案。 对于 $c_i$ 从 $a_i$ 变成 $b_i$ 的一次修改,$c_i$ 一定变大,对 $d$ 的影响为 $\forall j\ge i,d_j\gets\max(d_j,b_i)$。 修改是区间取 max,更新答案形如历史最小值,力大砖飞,直接用[吉司机线段树](https://oi-wiki.org/ds/seg-beats/)维护。 时间复杂度 $O(n\log^2 n)$,但是跑得很快。 代码太丑不放了。