Maintain Segment-Tree Range Sums
Checking your account…
Sign in to save your code and progress across devices. The lesson and problem statement remain public.
Loading the interactive Practice workspace.If it does not appear, the problem and learning material remain readable, but browser execution is unavailable.Reload Practice workspace
Problem
Implement segment_tree_ranges(values, operations). Operations are ["sum", left, right] with inclusive bounds or ["update", index, value]. Return one number per sum operation and do not mutate values.
Starter code
def segment_tree_ranges(values, operations):
passTest cases
range-and-update
{
"args": [
[
2,
1,
5,
3
],
[
[
"sum",
1,
3
],
[
"update",
2,
4
],
[
"sum",
0,
2
]
]
]
}Expected: [9,7]
single-value
{
"args": [
[
8
],
[
[
"sum",
0,
0
],
[
"update",
0,
-2
],
[
"sum",
0,
0
]
]
]
}Expected: [8,-2]
Wizard outline
- Step 1: Build the segment tree
Place values in leaf slots and compute every parent sum bottom-up. A correct root sum proves the compact two-level indexing layout before range logic.
- Step 2: Query an inclusive range
Translate inclusive bounds to leaf indexes and consume the half-open interval inward. The iterative two-pointer walk selects only nodes fully covered by the requested range.
- Step 3: Propagate a point update
Replace one leaf value and recompute each ancestor until the root. Updating ancestors keeps future range queries consistent without rebuilding the tree.
Footguns and prerequisites
- Mixing inclusive input bounds with a half-open internal query drops the right endpoint.
- Updating a leaf without rebuilding its ancestors leaves future sums stale.
- trees and graphs
Reviewed references
Recommended approach and implementation
Use a 2n iterative segment tree, a half-open boundary walk for sums, and ancestor recomputation for updates.
Why it works: Every internal node stores the sum of its leaf interval. A range query partitions the requested interval into disjoint stored segments, and an update repairs exactly the ancestors whose interval contains the changed point.
def segment_tree_ranges(values, operations):
size = len(values)
tree = [0] * (2 * size)
tree[size:] = values
for index in range(size - 1, 0, -1):
tree[index] = tree[2 * index] + tree[2 * index + 1]
def range_sum(left, right):
left += size
right += size + 1
total = 0
while left < right:
if left % 2:
total += tree[left]
left += 1
if right % 2:
right -= 1
total += tree[right]
left //= 2
right //= 2
return total
def update(index, value):
index += size
tree[index] = value
while index > 1:
index //= 2
tree[index] = tree[2 * index] + tree[2 * index + 1]
results = []
for operation in operations:
if operation[0] == "sum":
results.append(range_sum(operation[1], operation[2]))
elif operation[0] == "update":
update(operation[1], operation[2])
return results