K:K维 D:dimension 维度

网上没找到KDtree在OI和c++方面的详解(可能大佬们都觉得这玩意太简单懒得写?),累死个人.jpg

KDTree相当于多维的线段树

算法流程

我们要构建一颗二叉树。

信息有多维的时候,每往下一层就换一维进行统计。

第一层:先竖着切过(7,2)

第二层:横着切过(5,4)和(9,6)

第三层:竖着切过(2,3)和(4,7)和(8,1)

注意:切的点是某一侧所有点按照某一维排序后的中位数

求中位数用nth_element(,,);不会用的可以学一下

nth_element(first,kth,end)作用:将第k_th元素放到它该放的位置(排序后的位置)上,其他的数会动,但动完后不一定有序。复杂度O(n)

这样就构造出一个二叉树了。

其他操作都在这个二叉树上进行。

建树的同时记录一下点的范围,以便询问的时候好剪枝

打标记啥的就类似于线段树。

求最值的话需要估价函数和剪枝,可以看一下洛谷的P4169 [Violet]天使玩偶/SJY摆棋子

不太理解的话建议配合下边的模板题+代码理解

时间复杂度

单次操作为\(n^{\frac{k-1}{k}}\)(其中k>=2)

不会证,想证明的看这里

模板题

P4148 简单题 题解

P5471 [NOI2019]弹跳 KDtree 题解

P4631 [APIO2018] Circle selection 选圆圈 题解

CF44G Shooting Gallery 题解

【模板】三维偏序(陌上花开) 三维KDTree裸题

P4169 [Violet]天使玩偶/SJY摆棋子需要用到估价函数

P2093 [国家集训队]JZPFAR

用到了求第k大的思想,用一个小根堆,往这个堆里面加入 k 个 极小值,然后将每个元素与堆顶元素比大小,如果大于堆顶元素的话,把堆顶弹出,再把这个元素加入,最后答案就是堆顶。

P6247 [SDOI2012]最近最远点对 裸题

P4357 [CQOI2016]K 远点对 裸题,思路类似于[十二省联考2019]异或粽子,先记录每个点的最远点对,排好序,取出哪个点就更新哪个点的下一远点对,用KDTree查询

P3769 [CH弱省胡策R2]TATT 裸题,貌似也可以用cdq套cdq来做

P6349 [PA2011]Kangaroos 暂时不会,让我研究研究