1 条题解
-
0
题目分析
我们有一个 的网格,每个格子有高度 。
要求统计所有矩形区域的数量,满足:- 矩形不能触及边界(即 $1 \le r_1 \le r_2 \le n-2, 1 \le c_1 \le c_2 \le m-2$)。
- 对于矩形内的每个格子 ,它必须严格小于:
- 左边相邻列同一行的格子
- 右边相邻列同一行的格子
- 上边相邻行同一列的格子
- 下边相邻行同一列的格子
换句话说,矩形内部每个格子都比它所在行左右边界外的格子和所在列上下边界外的格子都要低。
关键观察
如果我们固定一个格子 ,它可能在多个矩形中。
对于它在某个矩形内是合法的,必须同时满足:- 它比它左边一列的格子 更高吗?不,不是左边一列,而是矩形的左边界列 ,这取决于矩形范围。
- 类似地,它比它右边一列的格子 高吗?不,是和 比较。
但是注意:矩形的边界 是固定的,所以对于格子 :
- 它必须比 小,即
- 它必须比 小,即
对列也是类似:
因此,对于每个格子 ,我们可以预处理四个方向上的“合法边界”:
预处理思路
定义:
left[i][j]:从 向左看,离它最近的大于等于它的列位置(不包括自己),即最大的 使得 ,如果没有则记为 。right[i][j]:从 向右看,离它最近的大于等于它的列位置(不包括自己),即最小的 使得 ,如果没有则记为 。up[i][j]:从 向上看,离它最近的大于等于它的行位置,即最大的 使得 ,如果没有则记为 。down[i][j]:从 向下看,离它最近的大于等于它的行位置,即最小的 使得 ,如果没有则记为 。
这样,当矩形左边界在 时,要求 (即 ),否则 不合法。
当矩形右边界在 时,要求 (即 )。类似地,对于行边界 ,要求 (即 ),(即 )。
问题转化
对于每个格子 ,它对矩形 合法的条件是:
- (记
U = up[i][j] + 2) - (记
D = down[i][j] - 2) - (记
L = left[i][j] + 2) - (记
R = right[i][j] - 2)
并且矩形本身不能碰边界:。
因此, 能存在于矩形中,当且仅当区间 和 非空,且区间 和 非空,并且矩形边界在有效范围内。
统计方法
我们枚举矩形的上边界 和下边界 (),然后看在这个行范围内,有哪些列区间 是合法的。
对于固定 ,我们要找 ,使得对于所有 和 ,都有:
也就是说,对于每个格子 ,它给出了对 的下界限制和对 的上界限制。并且这个限制对 在 内都要满足。
列限制的合并
对于固定的 和列 ,我们看第 列在行区间 内的格子。
要求对于这些格子中的每一个,都有 且 。因此,对于列 ,定义:
colL[r1][r2][j]= 行区间 内第 列所有格子的left[i][j]+2的最大值。colR[r1][r2][j]= 行区间 内第 列所有格子的right[i][j]-2的最小值。
如果对于某个 ,
colL > colR,那么这一列不可能出现在任何合法矩形中(自身矛盾)。
最终统计
对于固定 ,我们得到了每个列 的限制区间 ,要求 且 对所有 成立。
因此,对于矩形列区间 合法,必须满足:
这是一个经典的区间合法性计数问题,可以用单调栈或双指针来做。
时间复杂度优化
直接枚举 再枚举列区间是 的,太大。
我们可以用以下优化:
-
预处理
left,right,up,down:用单调栈,。 -
枚举 时,逐步增加 ,并维护
colL[j]和colR[j]的当前值(取 max/min 更新)。 -
对于当前 ,我们要计算列区间的数量,满足:
- 对区间内所有 , 且 。
可以换个角度:对于每个 ,求最大的 使得条件成立。
即要求 ,并且 。可以用双指针:
- 固定 ,让 向右扩展,同时维护区间内
colL的最大值maxL和colR的最小值minR。 - 当
c1 < maxL或c2 > minR时停止扩展。 - 如果扩展停止时满足 且 且 ,则这是一个合法列区间。
- 注意:当 增加时,
maxL和minR可以更新,可以用两个单调队列维护滑动窗口最大值/最小值。
这样对于固定 ,统计列区间是 的。
总复杂度:。
复杂度分析
- 预处理:
- 主循环:
对于 , 最大约 ,显然会超时,需要进一步优化。在实际竞赛中,本题可能有更优的 或 解法,但这里给出的是直观的思路框架。对于满分需要进一步优化(例如用二维单调栈直接统计矩形)。
- 1
信息
- ID
- 5713
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者