1. Splay 动态维护括号序列/文本编辑器的工程实现中隐式 Treap(按位置分裂)实现 O(log n) 插入/删除/翻转
说明如何用隐式 Treap(按位置分裂)实现 Splay 动态维护括号序列/文本编辑器,使插入/删除/翻转都达到 O(log n)?
- 隐式下标:以子树大小代替键值
- split/merge 实现区间操作
- 懒标记翻转与下推
隐式 Treap 以"子树大小"作为隐式键值:节点不存键,而是用子树节点数表示其覆盖的位置范围。split(根, k) 把前 k 个元素与剩余元素分裂成两棵,merge 按随机优先级合并两棵。插入:先把序列分成前 x 个和后,再在中间 merge 新节点;删除:split 出目标区间后直接丢弃;翻转:split 出区间后给该子树打懒标记,再 merge 回。由于每操作只沿树高 O(log n) 的路径,复杂度均为 O(log n)。这使隐式 Treap 能高效维护括号序列合法性(用前缀和最小值)与文本编辑器的任意位置编辑。
隐式 Treap 的关键是用"位置"而非"值"作为访问依据,因此天然适合序列的区间操作。随机优先级保证期望平衡,无需旋转就能实现分裂合并,配合懒标记可处理翻转。括号序列维护时在节点上维护区间和、最小前缀和,翻转通过懒标记切换,合并时 O(1) 合并信息。
// split(root, k): 返回 [前k个, 剩余] 两棵
// merge(a, b): 按优先级合并(a 全部在 b 之前)
// 翻转 [l,r]: x=split(root,l-1); y=split(x.r, r-l+1); y.l.rev^=1; root=merge(x.l, merge(y.l, y.r))