[ABC248Ex] Beautiful Subsequences

发布时间 2023-09-08 22:11:10作者: 小篪篪

题意

给定排列 $ P_n $ 和整数 $ k $,求满足如下条件的点对 $ (l, r) $ 数量。

  • $ 1 \le l \le r \le n $。
  • $ \max_{i = l}^rP_i - \min_{i = l}^rP_i \le r - l + k $。
数据范围
  • \(1 \leq N \leq1.4 \times 10^5\)
  • \(P\)\(1\)\(N\) 的排列
  • \(0 \leq K \leq 3\)

题解

这道题可以说是一道很典型的题, 因为它的两种做法刚好能说明处理区间套区间问题的常见解法。
注意这里的区间套区间是指的对于给定的 \((L, R)\) , 问题面向所有满足 \(L \leq l \leq r \leq R\) 的区间 \([l, r]\)
而这道题的 \((L, R)\)\((1, n)\)

解法1

从左到右扫描右端点, 维护右端点变化对于所有左端点的影响。
先将 \(\max_{i = l}^rP_i - \min_{i = l}^rP_i \le r - l + k\) 变形为 \(\max_{i = l}^rP_i - \min_{i = l}^rP_i - r + l \le k\) 。 因为 \(P\) 是排列, 所以我们能得到, \([l, r]\) 中一定有 \(r - l + 1\) 个不同的数, 所以 \(\max_{i = l}^rP_i - \min_{i = l}^rP_i\) 必定大于 \(r - l\) , 否则无法满足有 \(r - l + 1\) 个不同数的要求。 换句话说, 我们要求的区间的条件可以加强为 \(0 \le \max_{i = l}^rP_i - \min_{i = l}^rP_i - r + l \le k\) , 由于 \(k\) 值很小, 想到维护最小的 \(k + 1\)\(\max_{i = l}^rP_i - \min_{i = l}^rP_i + l\) ,以及对应的数量。 由于固定了 \(r\) 以后 \(\max_{i = l}^rP_i\)\(\min_{i = l}^rP_i\) 都具有单调性, 所以我们移动右端点后的更新相当于对一段区间的最大值赋成一个值, 一段区间的最小值赋成一个值。 所以我们可以维护最小的 \(k + 1\)\(\max_{i = l}^rP_i + l\) 和最小的 \(k + 1\)\(-\min_{i = l}^rP_i + l\) , 区间赋值的时候就能比较方便的更新和维护。 最后, 把这一堆东西放到线段树上即可, 当然, 也许我们可以用单调栈维护, 减少一个 \(\log\) 但由于需要考虑的东西太多, 可行性还未知且性价比不高, 所以就不多赘述。
最后时间复杂度 \(O(nk\log n)\)

这种方法的核心就是移动右端点端点以后对左端点的影响可以通过数据结构在短时间内查出。 典型的题目有 Intervals of Intervals比赛 , 其中比赛也给了我们一个启示, 对于并不是询问整段的问题, 单纯去枚举右端点并不能完全解决问题, 因为询问本身有 \(q\) 个, 但是历史最值, 历史求和却能很好的解决枚举右端点的时间复杂度。

解法2

考虑按照跨越某些位置对区间分类。
首先二分, 取 \(mid = \lfloor \frac{L + R}{2} \rfloor\) , 那么我们只需要考虑 \(L \leq l \leq mid, mid < r \leq R\) 的区间, 剩下的区间直接递归 \([L, mid]\)\([mid + 1, R]\) 即可, 二分保证了时间复杂度, 所以处理左端点在 \([L, mid]\) 中, 右端点在 \([mid + 1, R]\) 中的区间时, 只要保证总时间是接近于线性的即可。
首先因为左右端点已经必过一个位置了, 所以我们可以用这个必过的位置来将一个两动端点的区间问题转变成两个一动一定端点的区间问题。 这样的好处就是, 两个动端点可以理解为一个坐标: \((l, r)\) , 问题就是一个平面上的问题了, 而通常平面上的问题都不好用比较快的算法解决。 如果只有一个端点是动端点就不一样了, 这就是一个数轴上的问题, 我们完全可以把区间信息转换成单点信息。
接着我们来考虑将问题转换, $\max_{i = l}^rP_i - \min_{i = l}^rP_i \le r - l + k $ 就变成了 \(\max\{\max_{i = l}^{mid}P_i, \max_{i = mid + 1}^rP_i\} - \min\{\min_{i = l}^{mid}P_i, \min_{i = mid + 1}^rP_i\} \le r - l + k\) 。 我们发现式子中有类似于 \(\max\{a_i, a_j\}\) 这种项, 这种东西没法直接处理, 所以考虑转化。 一个很常见的转换方法就是将最值问题转化为限制问题, 即钦定 \(a_i \leq a_j\) , 然后再对 \(j\)\(i\) 的取值做出限制。 这道题我们就按照这种方式来尝试。 首先我们发现 \(\max_{i = l}^{mid}P_i\)\(\min_{i = l}^{mid}P_i\) 有单调性, 所以如果分别限制两者大于或小于一个值就等价于有两个限制 \(i\) 的取值区间, 当然, 在取并后, 我们就成功的将 \(i\) 的范围锁定在了一个区间内。 接下来再考虑原本的限制, 即 \(\max\{\max_{i = l}^{mid}P_i, \max_{i = mid + 1}^rP_i\} - \min\{\min_{i = l}^{mid}P_i, \min_{i = mid + 1}^rP_i\} \le r - l + k\) , 在我们进行最值的转换后, 成功地将取最值项转化成了只和 \(i, j\) 其中一个有关, 那么整个式子就可以看成 \(a_i \leq a_j + k\) 其中 \(a_i\)\(a_j\) 都只和 \(i\)\(j\) 的值有关, \(k\) 是常数项。 那么我们就可以得到一个算法, 枚举 \(j\) , 再枚举最值限制关系, 求有多少个 \(i\) 满足下标在限制区间内, 并且 \(ai\) 满足小于等于 \(a_j + k\)注:这里的 \(a_i\)\(a_j\) 并不是定值, 但只跟最值限制关系和下标有关), 这就变成了二维数点问题, 可以使用 cdq 分治或者树状数组 \(O(len \log(len))\) 解决。

这个方法的核心就是以跨过特定位置对区间分段, 这样的好处上面也讲了是可以把双动点区间转化为两个单动点区间。 常见的就是分治这样去设位置, 这样能保证时间复杂度。 但还有一种比较特殊的分法, 就是按照最值来分, 常见的就是最大值最小值, 也就是笛卡尔树, 这种分法就是为了给区间创造特殊性。 当然这种跨特殊位置的思路不仅是用在序列上的, 可以发现树分治也是用的同样的思路, 不停的以是否越过重心对链分类。