【问题标题】:Counting total number of points inside 2 circles计算2个圆圈内的总点数
【发布时间】:2013-03-05 09:10:44
【问题描述】:

有 2 个圆,它们的中心是固定的,将作为输入给出。那么将有n个点,其x和y坐标作为输入给出。

最后会有q个查询。对于每个查询,将给出两个圆的半径(让它们分别为 r1 和 r2)。输出每个查询的第一个圆或第二个圆内的总点数。如果点到圆心的距离小于或等于圆的半径,则该点位于圆内。

约束:n, q

我正在寻找 O(nlogn) 或 O(nlog^2n) 预处理,然后是每个查询的 O(logn) 算法。 每个查询的 O(n) 解决方案太慢。任何想法如何破解这个?

【问题讨论】:

  • 创建两个数组,根据点的距离对点进行排序。这需要 O(n log(n)) 进行排序。然后在两个数组中对每个查询进行二进制搜索,以找到相应圆圈中的最后一个点。这需要 O(log(n))。
  • 如果一个点在两个圆圈内,那么它将被计算两次

标签: algorithm data-structures


【解决方案1】:

O(log2N) 查询时间的解决方案。

  1. 每个查询更容易计算两个圆圈之外的点,然后从总点数中减去结果。
  2. 使用笛卡尔坐标更容易。这样 X 将是与 C1 的距离,Y - 与 C2 的距离。在这种情况下,我们只需要找到X > r1 && Y > r2 区域内的点数。
  3. 为每个点分配值“1”。现在我们只需要找到给定区域中的值的总和。在一维情况下,这可以通过 Fenwick 树来完成。但如果使用 2D Fenwick 树,则 2D 情况并没有太大区别。
  4. 2D Fenwick 树应该占用太多空间(1012 值与给定的约束)。但是 Fenwick 树的二维数组非常稀疏,因此我们可以使用哈希映射来存储其值并将空间需求(和预处理时间)减少到 O(N log2N)。李>

【讨论】:

  • +1:这看起来不错。如果您还通过增加 Y 对查询进行排序并逐渐将点插入到 Fenwick 树中,那么您也许可以只使用 X 上的一维 Fenwick 树。
  • 这看起来不错。但是如何实现具有如此巨大约束的二维 Fenwick 树呢?如果距离总是一个整数,那么你的想法就足够了。但距离可能总是不是整数。在这种情况下,如果我们使用距离的平方,那么芬威克树将需要 10^12 * 10^12 的空间。尽管它会很稀疏,但我认为这还不够吗?
  • @user2040997:Fenwick 树的每个维度最多更新每个点的 log N 个值。这意味着哈希映射应存储最多 N*log^2(N) 个值,对于给定的约束,这意味着 4 亿个值。顺便说一下,这个数字不依赖于 x,y 的约束。如果您不需要在线回答查询,您可以使用 Peter de Rivaz 建议的一维 Fenwick 树。在这种情况下,不需要哈希映射。大小为 N 的数组对于一维 Fenwick 树就足够了(因为只有 N 个不同的距离)。 This answer 提供了更多一维案例的详细信息。
  • 如果 Fenwick 树对内存的要求太高了,你可以用 kd-tree 妥协,在 X 方向的中值处分裂,然后在 Y 方向的中值处等等。你可以统计每个子树下的点数;然后如果一个矩形完全在 X > r1 && Y > r1 区域,我们将它的点添加到我们的运行总数中;如果它完全在这个范围之外,我们就把它扔掉;否则我们分开。我认为这应该是“随机”查询的 O(N^(1/2)) 查询时间 - 但可能会构建所有点都在边界上的非常糟糕的情况......
【解决方案2】:

设 C1、C2 为圆盘的中心。设 Pi, i = 1 ... n, 为点。令 Qj, j = 1 ... q, 为第 j 个查询,Qj = (qj1, qj2)。

  1. 对于每个点 Pi,计算 d(Pi, Ck),k = 1 或 2。将其放入已排序的多重映射中:Mk(d(Pi, Ck)) 包含 Pi。这可以在 O(nlogn) 中完成(这实际上就像对距离列表进行排序一样)。
  2. 对于每个查询 Qj,在 Mk 的键上对 qjk 进行二分搜索,这可以在 O(logn) 中完成。
  3. 对于每个查询 Qj,取小于或等于上面找到的键的多映射值的并集。

【讨论】:

  • 联合步骤有多快?对于较大的 r1,r2 值不是 O(n) 吗?
  • 如何在 O(logn) 中取多图的值的并集?我相信这在最坏的情况下可能需要 O(n)。
  • @user2040997 我相信这是合并排序的(联合)最佳方案。
猜你喜欢
  • 2020-10-28
  • 2014-07-13
  • 1970-01-01
  • 2010-12-23
  • 2012-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多