[EC Final 2021] Vision Test

[EC Final 2021] Vision Test

\(K = \frac{a}{c},B = \frac{b}{c}\),则题目需要找到 \(K,B\) 使得满足 \(a_i = \lfloor{Ki+B}\rfloor\).

如果固定 \(K\),考虑 \(B\) 需要满足的条件:

\[a_i \le Ki+B < a_i+1 \]

\[\max(a_i-Ki) \le B < \min(a_i+1-Ki) \]

则如果 \(\min(a_i+1-Ki)>\max(a_i-Ki)\),那取 \(B = \max(a_i-Ki)\) 就得到了一组解。

如果不满足的话,也就是此时 \(\min(a_i+1-Ki)-\max(a_i-Ki)\le 0\)

\(i_{\min}\) 为取到 \(\min(a_i+1-Ki)\) 的下标 \(i\)\(i_{\max}\) 为取到 \(\max(a_i-Ki)\) 的下标 \(i\)

则如果 \(i_{\min} > i_{\max}\),增大 \(K\) 会使 \(a_{i_{\min}}+1-Ki_{\min}-(a_{i_{\max}}-Ki_{\max})\) 减小,从而不可能成立,因此此时要减小 \(K\)。同理,若 \(i_{\min}<i_{\max}\) 则要增大 \(K\)

不难发现 \(K\) 满足可二分性。于是在 Stern-Brocot Tree 上二分 \(K\),这同时能满足题目中字典序的要求。

由于 \(K\) 在 Stern-Brocot Tree 中的深度很大,二分时要每次跳一条链才能保证复杂度。每次在链上二分求出能跳的长度,总共 \(O(\log^2 V)\) 次调用 check。实际上使用倍增二分,只有 \(O(\log V)\) 次调用 check,因为 check \(O(t)\) 次后值域会变为原来的 \(2^t\) 级别。

接下来问题是对于一个区间,给定 \(K\),查询 \(\max(a_i-Ki)\) 及其下标,\(\min\) 的问题同理。

可以直接用回滚莫队(不删除莫队)制作出区间凸包信息,然后在凸包上二分查询,时间复杂度 \(O(n\sqrt q + q\log V \log n)\)

当然也有多种 polylog 做法,比如对序列进行分治,每次处理跨过 \(mid\) 的询问,需要处理出 \([ql,mid],[mid,qr]\) 两个前缀凸包的信息。

建前缀凸包的过程是加入一个点,弹出栈中的若干个点。那可以看作当前点向弹栈后下一个点连边,形成一棵树,前缀凸包信息就是一条当前点到根的链,查询时在树链上倍增即可替代凸包上二分。时间复杂度 \(O(n\log^2 n + q\log V\log n)\)

Code

posted @ 2025-10-29 22:29  Rainbow_qwq  阅读(29)  评论(0)    收藏  举报