二维莫队,顾名思义就是每个状态有四个方向可以扩展。

二维莫队每次移动指针要操作一行或者一列的数,具体实现方式与普通的一维莫队类似,这里不再赘述。这里重点讲块长选定部分。

块长选定

记询问次数为 ,当前矩阵的左上角坐标为 ,右下角坐标为 ,取块长为

那么指针 移动了 次,而指针 移动了 次。

所以只需令 ,即 即可。

注意这样计算 的结果 可能为 注意特判

最终,计算部分时间复杂度是 ,加上对询问的排序过程,总时间复杂度为

例题 1

输入一个 的矩阵,矩阵的每一个元素都是一个整数,然后有 个询问,每次询问一个子矩阵的权值。矩阵的权值是这样定义的,对于一个整数 ,如果它在该矩阵中出现了 次,那么它给该矩阵的权值就贡献

数据范围: 矩阵元素大小

例题 2

给你一个 的矩阵, 次询问,每次询问一个子矩形的第 小数。

数据范围:

首先和上一题一样,需要离散化整个矩阵。但是需要注意,本题除了需要对数值进行分块,还需要对数值的值域进行分块,才能求出答案。

这里还需要用到奇偶化排序进行优化,具体内容请见 普通莫队算法

对于本题而言,时间限制不那么宽,注意代码常数的处理。取的块长计算值普遍较小, 都取最大值时块长大约在 左右,可以直接设定为常数来节约代码耗时。