用于保存和检索平面中的点的数据结构

Data structure to hold and retrieve points in a plane

定义 1: 点 (x,y) 是控制点 (x',y') 当且仅当 x < x' 且 y < y'。

定义 2: 点 (x,y) 由点 (x',y') 控制当且仅当 x' < x 且 y' < y。

我正在尝试提出支持以下操作的数据结构:

我尝试使用多个 AVL 树来解决它,但无法提出足够优雅的解决方案。

Point (x,y) is controlling point (x',y') if and only if x < x' and y < y'.

Point (x,y) is controlled by point (x',y') if and only if x' < x and y' < y.

让我们假设 (x,y) 是正方形的中间。 (x,y) 是 B 方块中的控制点,并被 C 方块中的点控制。

所需的输出是点数 (x,y) 控件减去点数 (x,y) 被控制。即B中的点数减去C中的点数,B-C(指A,B,C,D中的点数简单A,B,C,D

我们可以很容易地计算出A+C中的点数,也就是x' < x的点数。 C+D(带 y'y 的点)、B+D(x'>x)也是如此。 我们将 A+C 加到 C+DA+2C+DA+B 加起来 B+DA+2B+D。 减去两个:A+2B+D-(A+2C+D) = 2B-2C,除以二:(2B-2C)/2 = B-C 就是需要的输出。

(我假设处理 1D 情况很简单,无需解释。)

以备日后参考

解决方案概要:

我们将维护两个 AVL 树。

  • Tree_X:将保留按 X 坐标排序的点。
  • Tree_Y:将保存按 Y 坐标排序的点。

两棵树中的每个节点都将保存以下附加数据:

  1. 左子树中的叶子数。
  2. 右子树的叶子数。

对于点 $(x,y)$,我们将定义区域 A、B、C、D:

  • 如果 x' < x 且 y' > y,点 (x',y') 在 A 中。
  • 如果 x' > x 且 y' > y,则点 (x',y') 在 B 中。
  • 如果 x' < x 且 y' < y,则点 (x',y') 在 C 中。
  • 如果 x' > x 且 y' < y,则点 (x',y') 在 D 中。

现在很明显 Score(x,y) = |C|-|B|。 然而 |A|+|C|, |B|+|D|, |A|+|B|, |C|+|D|可以很容易地从我们的两个 AVL 树中检索到,我们很快就会看到。 并注意 [(|A| + |C| + |C| + |D|) - (|A| + |B| + |B| + |D|)]/2 = |C|-|B|

所需操作的实现:

  • Add(x,y) - 我们将向我们的两个 AVL 树添加点 (x,y)。由于我们存储的额外数据仅在插入路径上受到影响,并且由于插入发生在 (logn) 中,因此 Add(x,y) 的总成本为 O(logn)。

  • Remove(x,y) - 我们将从我们的两个 AVL 树中删除点 (x,y)。由于我们存储的额外数据仅在删除路径上受到影响,并且由于删除发生在 (logn) 中,因此 Remove(x,y) 的总成本为 O(logn)。

  • Score(x,y) - 我将展示如何计算 $|B|+|D|$,就像其他人以类似的方式和相同的复杂性成本所做的那样。显然$|B|+|D|$是满足$x' > x$的点数。为了计算这个数字,我们将:

    1. 在 AVL_X 中找到 x。复杂度 O(logn).
    2. 在Tree_X中向上走,直到根,每次向右转,我们将对儿子的左子树中的元素数求和。复杂度 O(logn)。

    Remove(x,y) 的总成本为 O(logn)。