6.19 CW 模拟赛 T2. 黄金星球
前言
没想到双指针, 只能度过相对失败的一生
思路
双指针
这好像没啥好说的, 维护一个滑动窗口, 滑着走即可
复杂度显然是 \(\mathcal{O} (nm)\)
离线算法
想到扫 \(l, r\) 都基本不能做啊
考虑扫值域
不难发现问题转化成 \(\mathcal{O} (n^2)\) 次加点和 \(\mathcal{O} (m)\) 查询矩形最大值
因为这个题是一个三维偏序
离线下来一个 \(w\) 变成了 \(l, r\) 的强制在线二维偏序\((\)应该是吧\()\)
发现这个题有一个非常牛的性质, 其中的数是有单调性的

其中红箭头为矩阵单调性方向
蓝线及蓝色矩阵为一个查询矩阵
不难发现插入点一定是按照红色箭头插入的, 形式化的讲就是同行从右往左加入, 同列从上往下加入\((\)行列不同是不能直接比较的\()\)
并且每次查询一定是查询最后插入的点
图上来看大概是这样的

因为放了 \((x, y)\) 必然放了 \((x + 1, y)\), 所以 \(x = C\) 对应的最大的 \(y\) 严格不降, 在图上的表示就是一直向下走
此时如何维护矩阵中所有点的最小值?
不难发现只有一些关键点是有作用的

也就是其中的红色节点
我们分两个部分讨论, 设 \(f_c\) 表示 \(x = c\) 上最下方的节点的 \(r\) 坐标
- 深红色节点
这些节点就是 \((x, f_x)\) - 浅红色节点
这些节点是 \((x, R)\), 因为 \(f_x > R\)
于是我们现在只需要支持动态维护 \(f_x\)
每次深红色节点就是区间询问 \((x, f_x)\) 最大值
浅红色节点一定是选择最左边那一个
维护「最左边那一个」只需要线段树上二分即可, 找到第一个 \(f_x > R\) 的位置
总结
区间和这种问题方便用双指针维护
而且显然是具有单调性的
离线算法中扫值域确实是一种很常见的做法
区间操作 + 一个可以二分的东西, 就可以考虑用线段树维护

浙公网安备 33010602011771号