Skip to content

动态简洁位向量

dynamic succinct bit vector · dynamic rank-select bitvector

在接近位串本身或零阶熵的空间内,统一支持位访问、动态插删与 rank/select 查询。

条目类型
模型

形式陈述

动态接口与计算模型

维护位串 B[0n1],接口包括 access、rank、select、insert 和 delete。本文采用

rank1(i)=0j<iB[j]

的半开区间定义;select1(k) 返回第 k 个 1 的零基位置,其中 k 从 1 开始。固定约定能避免插入点附近最常见的一位偏差。

分析通常在 word-RAM 上进行,字长 w=Ω(logn)。一项结果必须同时说明查询时间、更新时间、主数据空间、冗余项以及是否压缩;只写“polylog 时间、succinct 空间”无法判断它是否真的优于普通动态数组。

分块平衡树

一个直接而可扩展的结构是把位串切成叶块,再用平衡多叉树按次序组织。每个内部节点为每个孩子保存两项摘要:

  • len:该子树包含多少 bit;
  • ones:该子树包含多少个 1。

access 或 insert 的位置查询按 len 做前缀选择。rank 沿同一路径累加所有已越过孩子的 ones。select 则反过来按 ones 找到包含第 k 个 1 的孩子,并把越过孩子的 len 加到答案位置。叶内用机器字、查表或小型压缩块完成局部操作。

树的关键不变量不是“每块恰好一样长”,而是块长落在带迟滞的区间,例如非边界叶保持在 [L,2L]。插入使叶超过上界时分裂;删除低于下界时,先向相邻叶借位,借不到再合并。迟滞避免一个位在边界附近反复触发分裂和合并。

直觉

动态位向量同时有两套坐标:按长度定位第几个 bit,按 ones 计数定位第几个 1。平衡树在每个子树保存这两种质量,便可用同一条下降路径分别完成位置选择和 occurrence 选择;叶块的迟滞则把局部搬移与树重平衡限制在可收费的范围内。

长度与一计数、查询路径及叶分裂
例子与边界

一次插入、查询与删除

B=101100 开始,在位置 2 前插入 1,得到

1011100=1011100.

新串前五位是 10111,所以 rank1(5)=4;第 3 个 1 位于零基位置 3,因此 select1(3)=3

若随后删除首位,位串变成 011100。根到首叶路径上的 len 都减一,ones 也因删去的是 1 而减一。此时 rank1(4)=3,第 3 个 1 位于位置 3。更新摘要必须发生在结构重平衡之后所对应的实际孩子上,否则分裂后的计数会挂在旧节点。

这个短轨迹也说明 position 与 occurrence 是两种不同的搜索坐标。insert/delete 依据 len 定位,select 依据 ones 定位;把两者共用一个未经标注的“size”字段,会在全零块或全一块上立即失效。

时间与空间目标

若树高为 O(logn/loglogn),每个节点能在一个或少数机器字内完成局部前缀选择,就可得到典型的 polylog 更新和查询时间。不同构造在 fanout、叶块编码、随机化与最坏/摊还保证之间取舍,静态位向量的 O(1) rank/select 通常不能在支持任意插删后原样保留。

不压缩时,目标是 n+o(n) bit 加上必要的全局元数据。零阶压缩版本希望接近

nH0(B)+o(n) bit,

其中 H0 只反映 0 与 1 的频率。达到这个式子要求叶块按内容编码,并把树指针、块边界、计数和空闲空间一起纳入冗余分析;仅把叶内容送入压缩器,内部节点仍用大量指针,不构成该空间结论。

推论与应用

动态文本索引中的状态传播

在动态二元序列或 wavelet tree 的某一层,插入一个字符会转化为位向量中的一次 bit insert。该层在插入位置前的 rank 决定字符进入下一层的坐标,因此更新不是“先插完所有层再计算”:每层都要用更新前的前缀计数确定下一位置,再把本层结构持久地改好。

删除沿相同路径传播。若某个叶块因删除而合并,逻辑位序必须保持不变,父节点的 len/ones 也要反映合并后的单个孩子。局部编码可以变化,但 access、rank 和 select 观察到的序列不能变化,这就是重平衡的语义不变量。

与相邻结构的区别

普通动态数组擅长尾部追加或按位置存取,却没有按 1 的累计数搜索的摘要。Rope 能在大文本上分段插删,但若节点只存字符数,不存 ones,就不能快速回答 rank/select。静态简洁位向量可为固定串建立更激进的常数时间索引,代价是插入会让后缀位置和索引整体失效。

压缩动态位向量也不是完整的动态全文索引。后者还需在多层序列、采样后缀位置和字符字母表之间维持一致坐标;本结构只提供其中可组合的一层接口。

边界与报告规范

全零位串使 select-one 无定义,全一位串则使零阶熵为 0,但仍要保存长度和支持位置更新。这两个极端会暴露“熵空间等于不占空间”的错误表述。API 应明确越界查询是报错、返回哨兵,还是只对有效 k 定义。

并发读写、持久化和崩溃恢复不包含在经典 word-RAM 结果中。工程实现若给叶预留大量空洞来降低搬移成本,应把这部分计入空间;若每次更新重编码整块,也应把 L 对更新时间的贡献计入,而不能只报告树高。

参考资料
  • Rajeev Raman, Venkatesh Raman and S. Srinivasa Rao, Succinct Indexable Dictionaries with Applications to Encoding k-ary Trees, Prefix Sums and Multisets, ACM Transactions on Algorithms, 2007.
  • Gonzalo Navarro and Yakov Nekrich, Optimal Dynamic Sequence Representations, SIAM Journal on Computing, 2014.
  • Gonzalo Navarro, Compact Data Structures: A Practical Approach, Cambridge University Press, 2016.
关系图谱8 个相邻概念 · 1 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组