Archipelago

Lec 3几何数据结构:点定位、范围树与分数级联

讲义完成更新于 2026-09-17

Lec 3 几何数据结构:点定位、范围树与分数级联(Geometric Data Structures: Point Location, Range Trees & Fractional Cascading)

对应 MIT 6.851 Lecture 3 · 讲师:Erik Demaine · 核心文献:Dobkin & Lipton (SIAMJC 1976), Chazelle & Guibas (Algorithmica 1986)

TL;DR

  • 本讲从时间维度转向高维空间几何数据结构,解决平面点定位(Planar Point Location)与正交范围搜索(Orthogonal Range Searching)。
  • 扫描线(Line Sweep)将空间连续变化转化为一维离散事件流,与部分持久化树对接后实现 O(log⁡n)O(\log n) 的静态点定位。
  • 范围树(Range Tree)通过嵌套结构实现高维搜索,利用分数级联(Fractional Cascading)将子数组定位开销从 O(log⁡n)O(\log n) 优化为 O(1)O(1),消除最后一个维度的对数因子;结合权重平衡树(BB[α]\text{BB}[\alpha])实现支持动态增删的分层范围树。

一、平面点定位与扫描线技术

1.1 问题定义与垂直射线射击

给定平面上的一个非自交平面直线图(PSLG,划分出若干多边形面域)。点定位问题要求:预处理后,对于任意查询点 (x,y)(x, y),快速返回其所属的多边形面。

点定位通常归约为垂直射线射击(Vertical Ray Shooting):从查询点 (x,y)(x, y) 发射一条垂直向上的射线,求其碰到的第一条线段。确定线段后,查表即可获知其下方的多边形面。

1.2 扫描线(Line Sweep)降维思想

扫描线是一种通用的降维范式:利用一条垂直于 xx 轴的垂线从左向右扫过整个平面。

  • 由于线段互不相交,当垂线扫描时,与垂线相交的各线段之间的 yy 轴相对垂直顺序是永恒不变的!
  • 线段的相对拓扑变化仅发生在离散的“事件点(Events)”:线段左端点(插入线段)与右端点(删除线段)。
  • 因此,扫描线截面上的几何关系可视为一维动态集合的前驱后继问题。

1.3 对接持久化数据结构

若用平衡二叉搜索树维护当前垂线上的线段顺序:

  • 当扫描线从 −∞-\infty 移动到 +∞+\infty 时,共发生 O(n)O(n) 次端点插入和删除事件。
  • 与持久化结合:使用第一讲介绍的部分持久化平衡二叉搜索树记录整条扫描线的历史演进(Dobkin & Lipton 1976)。
  • 查询过程:给定点 (x,y)(x, y),首先二分查找 xx 对应的版本号 vxv_x;然后在版本 vxv_x 的持久化树中以 yy 为键做后继查找。
  • 复杂度:预处理时间 O(nlog⁡n)O(n \log n),空间复杂度严格为 O(n)O(n),单次点定位查询时间为 O(log⁡n)O(\log n)。

二、正交范围搜索与嵌套范围树

2.1 正交范围搜索定义

给定 dd 维空间中的 nn 个点,对于轴对齐查询超矩形 R=[a1,b1]×⋯×[ad,bd]R = [a_1, b_1] \times \dots \times [a_d, b_d],支持三种查询变体:

  • 存在性查询:RR 内部是否存在点;
  • 计数查询:计算落在 RR 内的点数;
  • 枚举查询:列出落在 RR 内的全部 kk 个点(理想复杂度为 O(Search Time+k)O(\text{Search Time} + k))。

2.2 一维到多维嵌套范围树

  1. 一维范围树:将所有点存在平衡 BST 的叶子中。内部节点存储子树区间的分割点。查询区间 [a,b][a, b] 时,分别定位到 aa 与 bb 的分叉节点,沿途挂接的 O(log⁡n)O(\log n) 棵子树即覆盖了整个区间。
  2. 二维嵌套范围树:
    • 主树以 xx 坐标为键构建一维范围树;
    • 主树的每一个内部节点 vv,均附带维护一棵辅助的二叉搜索树 Ty(v)T_y(v),存储 vv 的子树中全部点按 yy 坐标排序后的集合。
    • 空间复杂度:每个点出现在由根到叶路径上的 O(log⁡n)O(\log n) 个辅助树中,总空间为 O(nlog⁡n)O(n \log n)。
    • 查询复杂度:在主树上筛选出 O(log⁡n)O(\log n) 棵典范子树;在每棵辅助树上二分查找 [a2,b2][a_2, b_2] 需 O(log⁡n)O(\log n),总查询时间为 O(log⁡2n+k)O(\log^2 n + k)。
  3. dd 维推广:递归嵌套 dd 层,查询时间为 O(log⁡dn+k)O(\log^d n + k),空间复杂度为 O(nlog⁡d−1n)O(n \log^{d-1} n)。

三、分层范围树与分数级联(Fractional Cascading)

在二维范围搜索中,我们在 O(log⁡n)O(\log n) 棵辅助树中反复对相同的区间端点 [a2,b2][a_2, b_2] 进行了独立的二分搜索。这存在极大的冗余。

3.1 分层范围树的构造

将辅助树替换为按 yy 坐标排序的数组:

  • 对于主树节点 vv,设其按 yy 排序的数组为 A(v)A(v),左右孩子分别为 vLv_L 与 vRv_R。
  • 在 A(v)A(v) 中的每个元素,额外维护两个预计算桥梁指针:
    • ptrL\text{ptr}_L:指向 A(vL)A(v_L) 中大于等于该元素的最小后继位置;
    • ptrR\text{ptr}_R:指向 A(vR)A(v_R) 中大于等于该元素的最小后继位置。
 主树节点 v:      A(v)   = [ 2,  5,  8, 12, 19 ]
                           │       │       │
                ┌──────────┴───────┼───────┴──────────┐
                ▼                  ▼                  ▼
 左孩子 v_L:  A(v_L) = [ 2, 8, 19 ]      右孩子 v_R:  A(v_R) = [ 5, 12 ]

3.2 常数步进传播

查询时:

  1. 仅在根节点的数组 A(root)A(\text{root}) 中进行一次常规的二分查找,耗时 O(log⁡n)O(\log n),定位 a2a_2 的下标。
  2. 当沿主树向下遍历 O(log⁡n)O(\log n) 个典范节点时,直接跟随预计算指针下降。由于父数组是子数组的超集,仅需跟随指针并在邻近常数个槽位内做常数次比较,即可在 O(1)O(1) 时间内精准获得子数组中的区间端点!
  3. 性能提升:二维正交范围搜索的查询时间由 O(log⁡2n)O(\log^2 n) 降至 O(log⁡n+k)O(\log n + k)!推广到 dd 维,查询时间降至 O(log⁡d−1n+k)O(\log^{d-1} n + k)。

四、分数级联的一般化理论(Chazelle & Guibas)

Chazelle 与 Guibas 将这一技术形式化为可在任意有向图上运行的抽象理论。

分数级联主定理

设 G=(V,E)G=(V, E) 为局部入度有界的催化图(每个点维护一个有序序列 LvL_v)。 通过将后继序列中比例为 α=1/2\alpha = 1/2 的元素交替抽取并向邻接前驱序列归并,生成增广序列 Lv′L'_v。 增广序列的大小满足几何级数收敛:

∣Lv′∣≤∣Lv∣+12∣Lnext′∣  ⟹  ∑v∣Lv′∣=O(∑v∣Lv∣)|L'_v| \le |L_v| + \frac{1}{2}|L'_{\text{next}}| \implies \sum_{v} |L'_v| = O\left(\sum_v |L_v|\right)

在不增加渐近存储空间的前提下,在 kk 个相关节点中的多点定位总耗时从 O(klog⁡n)O(k \log n) 降低为 O(k+log⁡n)O(k + \log n)。

五、动态化与权重平衡树(BB[α]\text{BB}[\alpha] 树)

分层范围树严重依赖静态数组与硬编码指针。为了支持动态插入与删除,必须采用权重平衡二叉树(Weight-Balanced Trees, BB[α]\text{BB}[\alpha] 树)。

5.1 权重平衡准则

高度平衡(如红黑树、AVL)仅约束路径长度,无法感知子树规模;而权重平衡树要求对于任意节点 vv:

size(left(v))≥α⋅size(v)且size(right(v))≥α⋅size(v)\text{size}(\text{left}(v)) \ge \alpha \cdot \text{size}(v) \quad \text{且} \quad \text{size}(\text{right}(v)) \ge \alpha \cdot \text{size}(v)

其中常数 α∈(0,1−1/2)\alpha \in (0, 1 - 1/\sqrt{2}),典型取值如 α=1/4\alpha = 1/4。

5.2 整体局部重构与摊还分析

  • 当插入或删除导致某个节点 vv 违背平衡条件时,直接将其整棵子树销毁,并在线性时间内重新构建为完全平衡树。
  • 势能论证:子树要从完全平衡态(比例 1/21/2)退化到违背 α\alpha 约束,必须经历 Ω(size(v))\Omega(\text{size}(v)) 次更新操作。因此,将 O(size(v))O(\text{size}(v)) 的全子树重构成本分摊到这些历史更新上,单次操作的均摊重构代价仅为 O(1)O(1)。
  • 动态 dd 维分层范围树达成:查询时间 O(log⁡d−1n)O(\log^{d-1} n),更新均摊时间 O(log⁡dn)O(\log^d n)。

六、几何数据结构全景对比

问题类型查询时间空间复杂度核心技术方案
静态平面点定位O(log⁡n)O(\log n)O(n)O(n)扫描线 + 部分持久化平衡树
动态平面点定位(水平)O(log⁡n)O(\log n)O(n)O(n)扫描线 + 完全回溯搜索结构
一维范围搜索O(log⁡n+k)O(\log n + k)O(n)O(n)一维范围树 / 平衡 BST
二维范围搜索(朴素)O(log⁡2n+k)O(\log^2 n + k)O(nlog⁡n)O(n \log n)二维嵌套范围树
二维范围搜索(分层)O(log⁡n+k)O(\log n + k)O(nlog⁡n)O(n \log n)分数级联(预计算定位指针)
dd 维范围搜索(分层)O(log⁡d−1n+k)O(\log^{d-1} n + k)O(nlog⁡d−1n)O(n \log^{d-1} n)多层嵌套 + 末维分数级联
动态 dd 维范围搜索O(log⁡d−1n+k)O(\log^{d-1} n + k)O(nlog⁡d−1n)O(n \log^{d-1} n)权重平衡树(BB[α]\text{BB}[\alpha])局部重构

七、我的理解

分数级联的本质:利用包含关系做搜索信息的无损继承

在多层嵌套结构中,每一层独立做二分搜索实际上是一种“失忆症”——在父节点中花费 O(log⁡n)O(\log n) 获得的键值相对位置,进入子节点后被全部丢弃,重新从头二分。 分数级联洞察到了几何包含关系的冗余度:子节点的所有元素本来就是父节点元素的子集。 通过将子集的一半“幽灵元素”逆向渗透到父列表中,父列表就成为了子列表的高保真采样(Sampling)。在父节点中完成的一局二分查找,不仅锁定了当前层的位置,还免费附赠了通往所有下游子节点的常数级近邻指针。这种“用极小空间(几何收敛常数倍)换取全路径搜索继承”的设计,是高级数据结构在去除无效计算上的极致体现。