《遇到困难睡大觉》
遇到困难睡大觉。(下面这张图是来指自己的)

首先整体把握一下,min 两个量如果都没有限制就很难做,于是考虑固定其中一个,显然是对称的不妨固定 \min.
朴素的想法是,枚举 i, p_i 钦定 \min \ge a_i + p_ik = x,此时对于每个 i 相当于限制 p_i \ge \lceil \frac{x - a_i}{k} \rceil = l_i,也就是能选的位置为一段后缀。
此时的目的是让最大值尽可能小,整体把握比较难从特殊的地方开始做起,在这里从 l_i 最小的元素开始考虑起:先考虑 l_i = 1 的元素,选择任意一个留下均不影响合法性,于是显然将 b_i 最大的留下,然后递归此过程。
上述过程显然可以使用堆维护,于是此时我们已经得到了一个 \mathcal{O}(n ^ 3 \log n) 的做法了,但这是远远不够的。
注意到钦定的最小值有 \mathcal{O}(n ^ 2) 个,因此这里最可能可以改进,不妨打个表看看那些枚举是不必要的。
容易观察到,对于固定的 i 在钦定的 \min \ge a_i + p_ik 存在至少一组合法方案时随 p_i 增大答案不降,于是只需找到最大的合法的 p_i,复杂度降至 \mathcal{O}(n ^ 2 \log n),但这是为什么?
重新审视一下我们本质上在做什么:当枚举的 p_i 增大 1,x 增大 k,每个位置的限制 l_i 增大 1,这启发我们可以这样看待问题:有 n 个元素,每个元素需要在 [l_i, +\infty) 上选择一个整点,每个元素选择的整点不同,同时额外限定整点只能选择在 [1, n] 当中,每次 p_i 增大所有元素可选区间整体右移一个单位。
这样每次有 n 个区间都动比较难分析,但由于是整体移动,因此我们可以 固定 l_i 移动 “[1, n]” 这个区间,不妨记移动后为 [t, t + n - 1] 此时枚举的最小值就变为 a_i - (t - 1)k,但最大值就是 p_i 取在 [t, t + n - 1] 内的位置再减去 (t - 1)k(也就是相对位置)。
这样 (t - 1)k 这部分就可以抵消,最小值可以视作为恒定的 a_i,最大值就可以视作 p_i 取在 [t, t + n - 1] 内的位置。
此时根据 Hall 定律(或者就是上面的贪心),t 存在限制:将 l_i 从小到大排序后,\forall i \in [1, n], l_i - t + 1 \le i,于是 t \ge \min\limits_{i = 1} ^ n l_i - i + 1.
现在就需要回到贪心做法本身,这个做法不太方便描述性质,因为前后关联性比较大,考虑换一种方式看待这个贪心:
此时我们选取的特殊元素为从 b_i 最大的开始考虑起,此时其就选择 p_i = l_i 既使得 b_i + p_ik 达到了下界,又使得选的位置尽可能靠前不影响剩余元素,于是这个贪心等价于:按照 b 从大到小每次找到 l_i 右边第一个空位填入。
于是在 t 右移动过程中,所有位置能在 [t, t + n - 1] 内匹配的相对顺序不变,但会有越来越多的元素能匹配到 t 这个左边界,因此每个元素最后填入的位置一定不降,又最小值不变,因此答案不升;同时根据这个新的贪心方法,我们得到了一个 \mathcal{O}(n ^ 2) 的并查集解法。
此时进一步地根据移动区间的转换,只需要枚举 \bmod k = c,这看起来是必要的,于是接下来再将贪心这个部分改进一下。
当 c 增大时,贪心是难以维护的,于是只好抛开这个贪心做法,注意到本质上我们就是要最小化最大值,于是考虑二分答案。
枚举 c 后再二分,相比于先二分全局答案再固定最小值 c 更加难维护,因为数据结构善于解决整体信息。(下面记二分的答案为 x)
此时对每个元素等价于区间匹配限制 p_i \in [l_i = \lceil \frac{c - a_i}{k} \rceil, r_i = \lfloor \frac{x + c - a_i}{k} \rfloor] 于此同时选择的 t 依然一定是取到原先一样的下界,对 [l_i, r_i] 与 [t, t + n - 1] 取交后,等价于在 Z 上选点的问题。
这本质上就是对 0 \le c < k 进行一个区间二分图匹配判定,经典结论是:只需对右部每个区间应用 Hall 定律,进一步地只需对每个限制区间端点构成的关键区间应用 Hall 定律
这里需要定位每个区间,于是考虑扫描线,扫描区间右端点 r_j,使用数据结构维护关于左端点 l_i 的信息 f_{i, j} = r_j - l_i + 1 - |N([i, j])| 其中 N([i, j]) 为左部限制区间完全被 [l_i, r_j] 包含的元素,于是原问题有解等价于 \forall 1 \le i \le j \le n, f_{i, j} \ge 0.
当然不能直接对每个 c 都做一遍扫描线,需要观察 c 增量 1 后信息的变化。
首先类似于证明内的观察,所有 i 之间 l_i, r_i 相对关系不变,因此 t 的取值就可以很方便考察;同时 |N([i, j])| 也保持不变。
进一步地对于原始的(不对 [t, t + n - 1] 取交的) l_i', r_i’ 不降,并且至多只会存在一个位置 +1,推论为 t 也不降且至多增加 1,进一步地可以求出在考虑 [t, t + n - 1] 交限制后 l_i, r_i 也满足该性质, 并且记增加位置为 pl_i, pr_i.
此时每对 f_{i, j} 的变化仅与 l_i, r_j 有关,且增量为 [-1, 1] 于是可以简单分类讨论得到可行的 c 区间:
- 若 f_{i, j} < -1 则任意时刻均非法。
- 若 f_{i, j} = -1 则当且仅当 r_j 增加,l_i 不变时合法,即 c \in [pr_j, pl_i).
- 若 f_{i, j} = 0 当且仅当 r_j 不变,l_i 增加时非法,即 c \in [pl_i, pr_j)
- 若 f_{i, j} > 0 则任意时刻均合法。
于是扫描线右端点 r_j 时,只需找到 f_{i, j} = -1 且 pl_i 最小的限制,最后再取交即可得到满足第二条限制的合法区间;对 f_{i, j} = 0 的类似。
求出第三条的每个非法区间后,补集转化为前缀 / 后缀交,然后与第二条限制求出的交查看是否有交即可。
此时的瓶颈等价于保证查找键值为定值 z 的信息,由于有下界的保证只需使用线段树维护最小和次小值。
此时总的复杂度为 \mathcal{O}(n \log n \log V) 其中 V 为答案最大的绝对值。
代码:无。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步