Segment Tree Principles and Implementation
Segment Tree is an efficient data structure for handling range query and range update problems, especially suitable for solving range minimum, maximum, sum, and similar queries.
I. Problem Background and Basic Concepts
Suppose we need to handle range operations on an array, for example:
- Query the minimum value in the range [L, R]
- Update the value at a specific position
Traditional brute-force methods have query time complexity O(n) and update O(1). Segment Tree optimizes both query and update to O(log n) through preprocessing.
The core idea of a Segment Tree is to recursively bisect intervals, where each node represents an interval:
- Leaf nodes: Represent intervals containing a single element
- Non-leaf nodes: Represent the merge of intervals from their left and right child nodes
II. Segment Tree Construction Process
Taking the array [2, 4, 1, 7, 5] as an example to build a sum Segment Tree:
-
Recursively Divide Intervals
-
Calculate Node Values Bottom-Up
[0,4]:19 ← [0,2]:7 + [3,4]:12 [0,2]:7 ← [0,1]:6 + [2,2]:1 [0,1]:6 ← [0,0]:2 + [1,1]:4
III. Range Query Operation
Query the sum of range [1,3]:
- Starting from the root node 0,4, the target range partially covers both children
- Left subtree 0,2: The target range [1,3] partially covers this node
- Continue querying the right boundary of the left subtree [2,2] (completely within the target range)
- Right subtree [3,4]: The target range partially covers
- Continue querying the left boundary of the right subtree [3,3] (within the target range)
- Merge results: arr[1]+arr[2]+arr[3] = 4+1+7=12
IV. Single Point Update Operation
Update the value at position 2 to 6:
- Recursively traverse from the root down to find the corresponding leaf node [2,2]
- Update the leaf node value: 1→6
- Backtrack and update all ancestor nodes:
V. Range Update Optimization (Lazy Propagation)
When updating an entire range, introduce lazy propagation:
- When updating a range, first mark the value to be updated, without immediately updating all child nodes
- Perform the actual update based on the mark during queries
For example, adding 3 to the range 0,2:
- Mark node 0,2 with "pending addition of 3"
- The actual update is delayed until query time
VI. Key Points for Code Implementation
class SegmentTree:
def __init__(self, data):
self.n = len(data)
self.size = 1
while self.size < self.n: # Calculate the nearest power of two
self.size *= 2
self.tree = [0] * (2 * self.size)
# Initialize leaf nodes
for i in range(self.n):
self.tree[self.size + i] = data[i]
# Build bottom-up
for i in range(self.size-1, 0, -1):
self.tree[i] = self.tree[2*i] + self.tree[2*i+1]
VII. Application Scenarios
- Range Minimum/Maximum Query (RMQ problem)
- Range Sum/Product Queries
- Range Updates (additions, assignments)
- Two-dimensional Segment Trees for matrix operations
Segment Tree, with O(n) preprocessing time, achieves O(log n) queries and updates, making it a standard solution for interval-related problems.