PrepStack · Markdown HTML

线段树区间聚合

区间查询数据结构 · HTML

数学 / 逻辑形态

给定结合运算 merge 与单位元 identity;维护 set(i,x) 和 query(l,r) 的半开区间聚合。

识别信号

容易误判的相似信号

SignalWhy it is different
静态幂等 RMQ无更新时 Sparse Table 可 O(1) 查询。
只有点加与前缀和Fenwick 更短且常数小。

核心不变量

每个内部节点始终等于左右孩子相邻区间的 merge 结果。

状态、转移与处理顺序

ItemDefinition
State2*size 的迭代树,叶子从 size 开始,空叶为 identity。
Transition更新叶子后沿父链重算;查询用左右累积器收集区间分解节点。
Frontier / orderl、r 从叶层相向上移,越过的完整节点区间被吸收到对应累积器。

Python 骨架

class SegmentTree:
    def __init__(self, a, merge=min, identity=float('inf')):
        self.merge, self.id = merge, identity
        self.n = 1
        while self.n < len(a): self.n *= 2
        self.t = [identity] * (2 * self.n)
        self.t[self.n:self.n+len(a)] = a
        for i in range(self.n-1, 0, -1):
            self.t[i] = merge(self.t[2*i], self.t[2*i+1])
    def set(self, i, value):
        i += self.n; self.t[i] = value
        while i > 1:
            i //= 2
            self.t[i] = self.merge(self.t[2*i], self.t[2*i+1])
    def query(self, l, r):
        l += self.n; r += self.n
        left = right = self.id
        while l < r:
            if l & 1: left = self.merge(left, self.t[l]); l += 1
            if r & 1: r -= 1; right = self.merge(self.t[r], right)
            l //= 2; r //= 2
        return self.merge(left, right)

正确性思路

  1. 自底向上建树使初始摘要正确。
  2. 点更新只影响叶到根的祖先,重算后恢复不变量。
  3. 查询选出的节点互不重叠且恰覆盖区间。
  4. 左右累积器保留顺序,所以非交换 merge 也正确。

复杂度

TimeSpaceParameters
构建 O(n),更新与查询 O(log n)O(n)n 为元素数,size 为向上取整的二次幂

边界条件

错误模式

PatternWhy it fails / fix
单位元错误identity 必须对领域和 merge 真正中性。
闭开端点混乱统一 query(l,r) 为右开。
右累积器反序应 merge(tree[r],right)。

选择与排除规则

相关模板

RelationTemplateBoundary
静态替代Sparse Table 静态 RMQ无更新且运算幂等

原创微型例子

环节内容
Resultquery(1,4) 从 1 变成 0。
Scenario数组 [5,1,7,2,4] 维护最小值,把下标 2 改为 0。
Walkthrough只更新该叶与祖先;查询用少量完整节点覆盖区间。

Recall prompts

我的补充