CF1793C 题解

我们先考虑怎么判断一个位置 $i$ 是否可以作为一个合法区间的右端点:不合法的区间个数小于 $i$ 这个值。

具体的,假设 $lmi_i$ 为 $i$ 左边第一个小于他的位置,且 $lmx_i$ 为 $i$ 左边第一个大于他的位置。那么 $i$ 作为右端点,其中 $\min(lmi_i, lmx_i)+1$ 直到 $i$ 作为左端点,都是不合法的区间(因为 $i$ 位置是最值)。再往左,也就是 $1$ 到 $\min(lmi_i, lmx_i)$ 作为左端点的,答案取决于左端点是否是最值。那么左端点要成为区间最大值,当且仅当是 $lmx_i$ 以及 $lmx_{lmx_i}$ 等等以此类推。那么左端点要成为区间最小值,也同理,当且仅当是 $lmi_i$ 以及 $lmi_{lmi_i}$ 等等以此类推。

而由于只要左端点不是 $i$ 这个位置,就不可能既为最大值又为最小值,所以我们只要求出有多少左端点为到 $i$ 这段区间的最大值,多少左端点为最小值即可。求出了一种可行方案的右端点 $i$ 之后,只要暴力从 $i$ 往左扫一遍找出合法的左端点即可。

上述的 $lmi_i$ 和 $rmi_i$ 用单调栈求解,由于要求出左边有多少个作为最大值或最小值的左端点,本来我们要暴力跳,但是我们可以用倍增优化。

时间复杂度 $O(n \log n)$ 级别,主要为倍增的时间复杂度。

代码

posted @ 2023-02-13 20:32  徐子洋  阅读(10)  评论(0编辑  收藏  举报  来源