![]() |
VOOZH | about |
Segment Tree is one of the most important data structures used for solving problems based on range queries and updates. Problems based on Segment Trees are very common in Programming Contests. This article covers all the necessary concepts required to have a clear understanding of Segment Trees.
Table of Content
A Segment Tree is a data structure that stores information about a range of elements in its nodes. It also allows users to modify the array and perform range queries in smaller complexity. For example, we can perform a range summation of an array between the range L to R while also modifying the array from range L to R all in log(N) time complexity.
The segment tree works on the principle of divide and conquer.
The segment tree is generally represented using an array where the first value stores the value for the total array range and the child of the node at the ith index are at (2*i + 1) and (2*i + 2).
There are two common approaches to construct a Segment Tree:
There are two important points to be noted while constructing the segment tree:
- Choosing what value to be stored in the nodes according to the problem definition
- What should the merge operation do
If the problem definition states that we need to calculate the sum over ranges, then the value at nodes should store the sum of values over the ranges.
Following are the steps for constructing a segment tree:
Since there are (log n) levels in the worst case, so querying takes log n time. For update of a particular index to a given value we start updating the segment tree starting from the leaf nodes and update all those nodes which are affected by the update of the current node by gradually moving up through the levels at every iteration. Updates also takes log n time because there we have to update all the levels starting from the leaf node where we update the exact value at the exact index given by the user.
A dynamic Segment tree is the one where the values of the array is not fixed i.e it has an extra operation where the value of the i'th index of the array can be changed. As per this change the segment tree performs dynamic changes to give the right result after the changes have been made.
It basically performs two operations:
The below table lists the query type and its time complexity for a segment tree:
Query Type | Description | Time Complexity |
|---|---|---|
Construction | Build a segment tree from an input array of Size n. | O(n) |
Point Update | Update the value of an element at a specific index. | O(log n) - Height of the segment tree. |
Range Query | Retrieve information about a specific range in the array (e.g., sum, min, max). | O(log n) - Height of the segment tree. |
Range Update | Update all elements in a specific range of the array. | O(log n) - Height of the segment tree. |
Optimize range updates by deferring updates until necessary. | O(log n) for query, O(log n) for update. |
In CP, there are many problems which requires querying range data of an array in fast time i.e. about O(log(n)), this is where segment tree comes handy, let us see the most common applications of segment tree during a CP contest:
Problem Requirement: Given Q number of Queries and an array of size N, the task is to process the queries of the form:
Brute force solution: For each query we can traverse form index L to R sum up those values in O(Q* N) total time
Segment Tree Solution: With a segment tree each query of the form 1 L R can be processed in O(Log N) hence giving a time complexity of O(Q * LogN)
Problem Requirement: Given Q number of Queries and an array of size N, your task is to process the queries of the form:
Brute force solution: For each query we can traverse form index L to R sum up those values in O(Q* N) total time.
Segment Tree Solution: With a segment tree each query can be processed in O(Log N) hence giving a time complexity of O(Q * LogN)
Problem Requirement: Many problems require the user to quickly retrieve the minimum or the maximum value in a range i.e. for Q queries you have to get min/max value for range L to R of an array.
Brute force solution: For each query we can traverse form index L to R to find min/max in O(Q* N) total time
Segment Tree Solution: A segment tree data structure can process each query in O(Log N) hence giving a total time complexity of O(Q * LogN)
Problem Requirement: Given an array of size N, you have to perform Q queries of the following form:
Brute force solution: For each query of type 1 can be performed in O(N) time while query of type 2 can be performed in O(1) time, giving an overall complexity of O(Q * N)
Segment Tree Solution: A segment tree can be used to perform both the queries in O(log N) time giving an overall complexity of O(Q* LogN)
Interval intersection and union operations on a segment tree with updates involve maintaining information about intervals and efficiently performing intersection and union operations on them, while also supporting updates to the intervals. It performs 3 operations:
Persistent Segment Trees |
Two-Dimensional Segment Tree |
Sparse Table |
Fenwick Tree |
Problem | Link |
|---|---|
Solve | |
Queries for elements greater than K in the given index range | Solve |
Solve | |
Solve | |
Solve | |