Loading docs/geometry/nearest-points.md +3 −3 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ $$B = \{ p_i \ \big | \ \lvert x_i - x_m \rvert < h \}$$ 对于 $B$ 中的每个点 $p_i$,我们当前目标是找到一个同样在 $B$ 中、且到其距离小于 $h$ 的点。为了避免两个点之间互相考虑,我们只考虑那些纵坐标小于 $y_i$ 的点。显然对于一个合法的点 $p_j$,$y_i - y_j$ 必须小于 $h$。于是我们获得了一个集合 $C(p_i)$: $$C(p_i) = { p_j\ \big |\ p_j \in B,\ y_i - h < y_j \le y_i }$$ $$C(p_i) = \{ p_j\ \big |\ p_j \in B,\ y_i - h < y_j \le y_i \}$$ 如果我们将 $B$ 中的点按照 $y_i$ 排序,$C(p_i)$ 将很容易得到,即紧邻 $p_i$ 的连续几个点。 Loading @@ -31,7 +31,7 @@ $$C(p_i) = { p_j\ \big |\ p_j \in B,\ y_i - h < y_j \le y_i }$$ 2. 将 $B$ 中的点按照 $y_i$ 排序。通常做法是 $O(n\log n)$,但是我们可以改变策略优化到 $O(n)$(下文讲解)。 3. 对于每个 $p_i \in B$ 考虑 $p_j \in C(p_i)$,对于每对 $(p_i,p_j)$ 计算距离并更新答案(当前所处集合的最近点对)。 注意到我们上文提到了两次排序,因为点坐标全程不变,第一次排序可以只在分治开始前进行一次。并且每次递归返回当前点集按 $y_i$ 排序的结果,上层直接使用下层的两个点集归并即可。 注意到我们上文提到了两次排序,因为点坐标全程不变,第一次排序可以只在分治开始前进行一次。我们令每次递归返回当前点集按 $y_i$ 排序的结果,对于第二次排序,上层直接使用下层的两个分别排序过的点集归并即可。 似乎这个算法仍然不优,$|C(p_i)|$ 将处于 $O(n)$ 数量级,导致总复杂度不对。其实不然,其最大大小为 $7$,我们给出它的证明: Loading @@ -47,7 +47,7 @@ $$C(p_i) = { p_j\ \big |\ p_j \in B,\ y_i - h < y_j \le y_i }$$ ## 实现 我们使用一个结构体来存储点,并定义用于排序的函数: 我们使用一个结构体来存储点,并定义用于排序的函数对象: ```cpp struct pt { Loading Loading
docs/geometry/nearest-points.md +3 −3 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ $$B = \{ p_i \ \big | \ \lvert x_i - x_m \rvert < h \}$$ 对于 $B$ 中的每个点 $p_i$,我们当前目标是找到一个同样在 $B$ 中、且到其距离小于 $h$ 的点。为了避免两个点之间互相考虑,我们只考虑那些纵坐标小于 $y_i$ 的点。显然对于一个合法的点 $p_j$,$y_i - y_j$ 必须小于 $h$。于是我们获得了一个集合 $C(p_i)$: $$C(p_i) = { p_j\ \big |\ p_j \in B,\ y_i - h < y_j \le y_i }$$ $$C(p_i) = \{ p_j\ \big |\ p_j \in B,\ y_i - h < y_j \le y_i \}$$ 如果我们将 $B$ 中的点按照 $y_i$ 排序,$C(p_i)$ 将很容易得到,即紧邻 $p_i$ 的连续几个点。 Loading @@ -31,7 +31,7 @@ $$C(p_i) = { p_j\ \big |\ p_j \in B,\ y_i - h < y_j \le y_i }$$ 2. 将 $B$ 中的点按照 $y_i$ 排序。通常做法是 $O(n\log n)$,但是我们可以改变策略优化到 $O(n)$(下文讲解)。 3. 对于每个 $p_i \in B$ 考虑 $p_j \in C(p_i)$,对于每对 $(p_i,p_j)$ 计算距离并更新答案(当前所处集合的最近点对)。 注意到我们上文提到了两次排序,因为点坐标全程不变,第一次排序可以只在分治开始前进行一次。并且每次递归返回当前点集按 $y_i$ 排序的结果,上层直接使用下层的两个点集归并即可。 注意到我们上文提到了两次排序,因为点坐标全程不变,第一次排序可以只在分治开始前进行一次。我们令每次递归返回当前点集按 $y_i$ 排序的结果,对于第二次排序,上层直接使用下层的两个分别排序过的点集归并即可。 似乎这个算法仍然不优,$|C(p_i)|$ 将处于 $O(n)$ 数量级,导致总复杂度不对。其实不然,其最大大小为 $7$,我们给出它的证明: Loading @@ -47,7 +47,7 @@ $$C(p_i) = { p_j\ \big |\ p_j \in B,\ y_i - h < y_j \le y_i }$$ ## 实现 我们使用一个结构体来存储点,并定义用于排序的函数: 我们使用一个结构体来存储点,并定义用于排序的函数对象: ```cpp struct pt { Loading