在一堆工程向的代码里翻来翻去总算还是学会了。
KD-Tree
作用
用来解决一类多维空间内的统计问题,在中多用于二维平面内的统计问题,如邻近查找、二维数点。
思想:
其实就是把一个空间割成了一块块,然后暴力统计贡献。以二维空间为例子,每次横着找个中点切一刀,再竖着找个中点切一刀,树上的一个节点代表了一个矩形。
二维统计就是类似于线段树,如果当前矩形被完全包含于询问矩形,就把贡献加上。
而临近查找就是在上,只不过最优化剪枝了一下而已,但是此算法复杂度似乎被证明是的了。
重构
对于插入,我们类似于平衡树的插入即可。
然而这样可能树的高度会有问题,每个点代表的矩形可能也会被拉成扁平状,所以要类似于替罪羊树的暴力重构。
注意:这里的重构要在不平衡的最高点进行,不然一次重构可能会被直接卡成。
细节
节点的左右儿子是不包含当前节点表示的真实节点的,所以统计的时候要另算。
在的时候要判断是否有左右儿子。
的时候要把节点删干净,一般左右儿子是一定要删的,其他看情况。
优化技巧
其实就是与出题人斗智斗勇,尽量防止自己被卡。
在邻近查找和多维最值查询的时候一定要最优化剪枝。
如果对于实数领域的几何类问题,最好在读入之后把点随机旋转一个角度,这样建出来的会更加平均,可以防止被卡成长条状。
Code:
1 |
|