在定位系统中,世界被认为是一个 $W \times W$ 的正方形区域,由 $1 \times 1$ 的方格组成。每个方格都有一个坐标 $(x,y)$ , $1 \leq x,y \leq W$。
有三种命令,意义如下:
0 W
初始化一个全零矩阵。本命令仅开始时出现一次。1 x y A
向方格 $(x,y)$ 中添加A个用户。A是正整数。2 X1 Y1 X2 Y2
查询 $X1 \leq x \leq X_2$ , $Y_1 \leq y \leq Y_2$ 所规定的矩形中的用户数量3
无参数 结束程序。本命令仅结束时出现一次。
链接
题解
二维动态数点问题。
有很多种解法,树套树,$\text{CDQ}$ 分治 + 树状数组,$\text{CDQ}$ 分治套 $\text{CDQ}$ 分治。
这里选择了最后一种方法,练习一下 $\text{CDQ}$ 分治。
首先要明确,第 $x$ 个维度的 $\text{CDQ}$ 分治解决的是所有在前 $x-1$ 次分治中划分的(左/右)都相同的询问中,左->右的贡献。
在这里叙述一下 $\text{CDQ}$ 套 $\text{CDQ}$ 解决三维偏序问题(也可以推广到更高维的一个过程):
以三维偏序为例子,我们的三元组令其为 $(a,b,c)$ 。
预处理(相当于消掉一个维度):
- 对第一维 $a$ 进行排序
对第一维分治 CDQ1d(L,R)
:
- 对第一维 $a$ 进行分治,递归处理
CDQ1d(L,mid)
和CDQ1d(mid,R)
- 按第二维 $b$ 进行归并,此时不计算答案,只记录在这次分治中,该询问/修改属于左半区间 $\text{LEFT}$ 或者 右半区间 $\text{RIGHT}$ 。
- 复制一份归并后的该区间 $[l,r]$ 的询问数组,用其进行第二维的分治。
对第二维分治 CDQ2d(L,R)
:
- 对第二维 $b$ 进行分治,递归处理
CDQ2d(L,mid)
和CDQ2d(mid,R)
- 按第三维 $c$ 进行归并,此时需要计算答案,记录一个临时变量 $\text{tmp}$ (树状数组)。如果归并左侧新加入的查询/修改在之前维度的分治中均属于左半区间 $\text{LEFT}$ ,则给 $\text{tmp}$ (树状数组)做对应的修改; 如果归并右侧新加入的查询/修改在之前维度的分治中均属于右半区间 $\text{RIGHT}$ ,则计算相关贡献。
可以发现,这个递归是可以再次嵌套的,只有最外面一维是需要计算贡献的,前面只要记录每一维的 $\text{LEFT}$ 或 $\text{RIGHT}$,在最后计算即可。
事实上,我们在最后一层递归需要计算的只有 $(\text{LEFT},…,\text{LEFT},x_1)$ 对 $(\text{RIGHT},..,\text{RIGHT},x_2)$ 的贡献。
为什么这样就可以计算完全呢?
我们考虑到,如果在前 $x-1$ 个维度其有任意一个维度被划分到了一个区间,那么他们就会共同进入一次分治,那么这两个询问/查询之间的影响就会在子问题里面被解决,所以我们这样做的正确性是可以保证的。
代码
|
|