Commit abdc915d authored by Xeonacid's avatar Xeonacid
Browse files

fix

parent 628807c3
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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$ 的连续几个点。

@@ -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$,我们给出它的证明:

@@ -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 {