PrepStack · Markdown HTML

Segment tree range aggregation

Range-query data structures · HTML

Formal shape

Given associative merge and identity, maintain set(i,x) and the aggregate query(l,r) on half-open intervals.

Recognition signals

False friends

SignalWhy it is different
Static idempotent RMQWith no updates, a Sparse Table answers in O(1).
Only point add and prefix sumA Fenwick tree is shorter and has smaller constants.

Core invariant

Every internal node always equals merge(left-child summary, right-child summary).

State, transition, and processing order

ItemDefinition
StateAn iterative array of length 2*size; leaves start at size and unused leaves hold identity.
TransitionAfter changing a leaf, recompute ancestors; a query collects its canonical decomposition into left and right accumulators.
Frontier / orderl and r climb inward from the leaf layer; complete nodes passed by either boundary enter its accumulator.

Python skeleton

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)

Correctness sketch

  1. Bottom-up construction establishes every initial summary.
  2. A point affects only ancestors of its leaf; recomputing them restores the invariant.
  3. Query nodes are disjoint and exactly cover the requested interval.
  4. Two ordered accumulators preserve correctness even when merge is not commutative.

Complexity

TimeSpaceParameters
O(n) build and O(log n) update/queryO(n)n elements; size is the next power of two

Edge cases

Error patterns

PatternWhy it fails / fix
Wrong identityIt must truly be neutral for merge over the value domain.
Inclusive/exclusive driftKeep query(l,r) right-exclusive.
Reversing the right accumulatorUse merge(tree[r],right).

Selection and exclusion rules

RelationTemplateBoundary
static alternativeSparse table static RMQThere are no updates and the operation is idempotent

Original micro-example

PartDetail
Resultquery(1,4) changes from 1 to 0.
ScenarioTrack minima in [5,1,7,2,4] and change index 2 to 0.
WalkthroughOnly that leaf and its ancestors change; a few complete nodes cover the query.

Recall prompts

My notes