Algorithm 使用线段树的矩形并集面积

Algorithm 使用线段树的矩形并集面积,algorithm,geometry,computational-geometry,Algorithm,Geometry,Computational Geometry,我试图理解可以用来计算一组轴对齐矩形的并集面积的算法 我下面介绍的解决方案如下: 我不明白的是: 段树是此数据结构的正确选择。它具有复杂性O(logn) 对于更新操作和O(1) 用于查询。我们需要使用每个节点的分数来扩充段树,并具有以下属性 每个节点对应于一个y-区间,该y-区间是节点范围内所有索引上的基本y-区间的并集 如果节点值为零,则分数为子代分数之和(如果节点为叶,则为0) 如果节点值为正值,则分数为对应于该节点的y间隔的长度 我们如何在O(n log n)中实现这一点 我的想法是创

我试图理解可以用来计算一组轴对齐矩形的并集面积的算法

我下面介绍的解决方案如下:

我不明白的是:

段树是此数据结构的正确选择。它具有复杂性O(logn) 对于更新操作和O(1) 用于查询。我们需要使用每个节点的分数来扩充段树,并具有以下属性

  • 每个节点对应于一个y-区间,该y-区间是节点范围内所有索引上的基本y-区间的并集
  • 如果节点值为零,则分数为子代分数之和(如果节点为叶,则为0)
  • 如果节点值为正值,则分数为对应于该节点的y间隔的长度
我们如何在O(n log n)中实现这一点

我的想法是创建一个段树,当我们在扫线时遇到范围(y范围作为矩形的高度)时,更新每个范围的值。然后针对每个间隔(排序x数组中的两个连续元素,通过查看段树中所有元素的总和,将Δx乘以该间隔中活动y范围的总长度)

这仍然会导致在段树的基础中有max(y)-min(y)元素

因此,我不确定这是O(n logn)-其中n是矩形的数量

非常感谢您的帮助


谢谢 根据您的理解,您将创建底部有11-1=10个节点的段树,如下所示:

请注意,我们在base中只有9个节点,因为第一个节点用于interval[1,2],下一个节点用于interval[2,3],依此类推

当您输入某个矩形时,您将根据其y坐标更新其范围,因此在x=0上遇到第一个矩形后,您的线段树将如下所示:

我们还需要使用一种称为延迟传播的方法来更新树上的活动间隔,因此所有活动间隔的总和都是1

所以,当前方法的复杂性类似于O(K logk),其中K=max(y)-min(y)

我们可以很容易地把它简化为O(n logn),其中n是矩形的数目

请注意,唯一重要的y坐标是存在的y坐标,因此在本例中为1,3,6,11

还要注意,这样的坐标最多有2*n

所以我们可以将所有坐标映射到一些整数,这样它们就更适合分段树了

这被称为坐标压缩,可以通过以下方式完成:

  • 在数组中存储所有y坐标
  • 对数组排序并删除重复项
  • 使用map或hashMap将原始坐标映射到其在排序数组中的位置
  • 因此,在我们的示例中,它将是:

  • [1,3,6,11]
  • 没有要删除的重复项,因此阵列仍然
    [1,3,6,11]
  • mp[1]=1,mp[3]=2,mp[6]=3,mp[11]=4
  • 所以现在算法保持不变,但我们可以使用段树,它的基中最多只有2*n个节点

    此外,我们还需要稍微修改片段树, 现在,我们不再保持y坐标的开或关,而是保持y坐标的开/关间隔

    所以我们将有区间[y0,y1],[y1,y2]的节点。。。对于y的所有唯一排序值

    此外,所有节点将向总和贡献y[i]-y[i-1](如果它们在范围内且处于活动状态),而不是一个

    因此,我们的新段树如下所示:

    我们如何在O(n log n)中实现这一点

    考虑每个矩形,您将更新二叉段树中的范围[x,y]。本质上,发生的是,你是

    • 在树中搜索x作为左边界(对数(N)次)
    • 在树中搜索y作为右边界(对数(N)次)
    假设为x找到的节点是[x,a],它有一个父节点[z,a],该父节点有一个兄弟节点[a,b]。显然,如果y不在[a,b]下,则[a,b]的整个跨度都被覆盖,因此您可以增加此节点,而不是[a,b]子树下的所有单独段节点

    因此,搜索/更新过程如下所示

    • 如果父节点[a,c]有两个子节点[a,b],[b,c],且左边界x在[a,b]中,则决定是否增加节点[b,c]中的值(取决于y是否大于c)
    • 如果父节点[a,c]有两个子节点[a,b],[b,c],且右边界y在[b,c]中,则决定是否增加节点[a,b]中的值(取决于x是否小于a)
    本质上,在深入到一个节点之前,决定是否更新其同级节点


    您决定是否更新的节点数为log(N)(对于x)+log(N)(对于y)。

    我们可以使用坐标压缩仅保留必要的坐标,以便在段树中只有O(N)个元素base@Photon你能再解释一下吗?或者任何我可以阅读的推荐链接?文本说“更新操作的复杂度为O(logn),查询的复杂度为O(1)”。由于树最多包含n个节点,最多更新n次,因此最坏情况为O(n logn)。实际上,O(n logm),其中m是树中的一些平均节点数,可以是√n(因此差异没有log那么显著√n=1/2 log n)。这可能是一个幼稚的问题-但在您的第一个图表中,每个节点上的值是否是其子节点的最大值?谢谢,我不确定我是否理解在遇到第一个矩形后,如何从第一个图形中得到第二个图形。正在更新的y范围应该是[3,6],不是吗?为了澄清,您能否指定每个节点内的值的含义?我想这会帮助我理解如何从f得到图2