Exercises — Segment tree — build, range query, point update
This page is a self-testing ladder. Each problem sits inside a difficulty level (L1 → L5). Read the problem, try it on paper, then open the collapsible solution. Every symbol used here is built in the parent note — if a term feels new, re-read the parent first.
Throughout, we use the running array unless a problem says otherwise:
We work with a sum segment tree (each node stores the sum of its range) unless stated. Heap indexing means node v has children 2v and 2v+1, root at index 1 — exactly as in the parent's Binary Tree layout.

The figure above shows the tree for this array. Every node is labelled with its range [lo,hi] on top and its stored sum inside. Point to it whenever a solution mentions a node.
Level 1 — Recognition
Recall Solution L1.1
The root [0,5] splits at into [0,2] (heap index 2) and [3,5] (heap index 3).
(a) Node 3 covers indices ==[3,5]==. Why: it is the right child of the root, so it holds the right half.
(b) Its sum is .
(c) One leaf per array element, so 6 leaves.
Recall Solution L1.2
Test in the parent's fixed order.
- No overlap needs or : here and . ✗
- Total overlap needs and : here . ✗
- Default → ==partial overlap==. The query boundary cuts through the root's range, so we must recurse into both children.
Level 2 — Application
Recall Solution L2.1
Post-order: children first. The split points are .
[0,5]→[0,2]and[3,5].[0,2]→[0,1]and[2,2].[0,1]→[0,0]and[1,1].[3,5]→[3,4]and[5,5].[3,4]→[3,3]and[4,4].
Now sum upward:
[0,1] = 2+1 = 3[0,2] = 3 + 5 = 8(the[0,1]sum plus leaf[2,2]=5)[3,4] = 3+7 = 10[3,5] = 10 + 4 = 14- Root
[0,5] = 8 + 14 = \mathbf{22}✓ check: .
Recall Solution L2.2
Wanted range [1,4].
- Root
[0,5]: partial → recurse.[0,2]: partial ( inside) → recurse.[0,1]: partial → recurse.[0,0]: no overlap () → return .[1,1]: total ( and ) → return . stop.
- subtotal
[0,1]part . [2,2]: total ( and ) → return . stop.
[0,2]contributes .[3,5]: partial → recurse.[3,4]: total ( and ) → return . stop.[5,5]: no overlap () → return .
[3,5]contributes .
- Total . ✓
Notice
[3,4]returned its whole precomputed sum — that is the speedup in action.
Level 3 — Analysis
Recall Solution L3.1
The root-to-leaf path for index 4:
root [0,5] → right child [3,5] (since ) → left child [3,4] (since ) → leaf [4,4].
Set leaf [4,4]=1. Repair on the way up (only ancestors):
- `[3,4] = a[3]+a[4] = 3+1 = 410$)
- `[3,5] = 4 + 4 = 814$)
- Root `[0,5] = 8 + 8 = \mathbf{16}22$)
Unchanged: [0,2], [0,1], all left-subtree nodes, and leaf [5,5]. Only the 4 nodes on the path moved, matching .
Recall Solution L3.2
A node expands (recurses both ways) only when it is partially overlapped — the query boundary or passes through its range. On any single level, the value can lie inside at most one node's range, and inside at most one node's range. So at most 2 nodes touch the left boundary + 2 the right boundary = 4 partial nodes per level. Everything strictly between and on that level is total overlap (returns instantly), and everything outside is no overlap. With levels, total work is . This is the same "expand only at the frontier" idea behind Divide and Conquer.
Level 4 — Synthesis
Recall Solution L4.1
Minimum is associative and defined over disjoint ranges just like sum, so the same tree shape works — only combine changes.
[0,2] = \min(2,1,5) = \mathbf{1}[3,5] = \min(3,7,4) = \mathbf{3}- Root
[0,5] = \min(1,3) = \mathbf{1}
No-overlap return: the identity of min, which is . Why: a non-contributing node must not change the answer, and for every . Returning here would be wrong — could shrink the true minimum. This is the exact trap the parent warns about.
Recall Solution L4.2
A prefix sum is exactly the range sum over [0,k], so
No new machinery needed — a prefix is a special range starting at index . For : . (Unlike a static prefix-sum array, this one survives point updates in — the reason segment trees beat prefix arrays under updates.)
Level 5 — Mastery
Recall Solution L5.1
Store a pair at every node.
- Leaf
[i,i]stores . - combine:
- if → take ;
- if → take ;
- if → take the smaller index, . This tie rule guarantees the leftmost maximum.
- No-overlap identity: — a value that loses every comparison and an index that loses every tie.
For the array the maximum is at index , so the root stores . The pair is a valid combine because it is associative — a requirement for any segment-tree merge.
Recall Solution L5.2
Each element in [l,r] needs one point update, and each point update costs . For elements the total is — and can be as large as , giving per range update. That is worse than a plain array's .
The fix is Lazy Propagation: store a pending "add" tag on a totally-covered node and push it down only when needed, restoring per range update. Compare also Fenwick Tree (BIT), which handles range-add/point-query variants more compactly.
Recall Solution L5.3
(a) : the tree is a single node = single leaf [0,0] storing . Root and leaf coincide; build hits the base case immediately. tree[] of size is more than enough.
(b) (empty range): every node reports no overlap (the condition or holds everywhere since ), so the query returns the identity ( for sum) — the correct "empty sum". No crash.
(c) [l,r] fully left of [0,n-1]: e.g. querying a range with . The root immediately satisfies → no overlap → returns identity . The recursion never descends. ✓
Recall Quick self-check (cloze)
A node is queried and its range lies inside [l,r] — this is the total overlap case, so we return its stored value and stop.
An update to index i changes exactly the ancestors on the root-to-leaf path of i.
The no-overlap return value is the identity element of combine ( for sum, for min).
A range update via repeated point updates costs ==, fixed by lazy propagation==.