Segment Trees for Competitive Programming
Last Updated :
20 Dec, 2023
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.
What is a Segment Tree?
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.
Structure of the Segment Tree:
The segment tree works on the principle of divide and conquer.
- At each level, we divide the array segments into two parts. If the given array had [0, . . ., N-1] elements in it then the two parts of the array will be [0, . . ., N/2-1] and [N/2, . . ., N-1].
- We will then recursively go on until the lower and upper bounds of the range become equal.
- The structure of the segment tree looks like a binary tree.
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).
Construction Of Segment Tree:
There are two common approaches to construct a Segment Tree:
- Recursive method
- Iterative method
1. Construction Of Segment Tree using Recursive Approach:
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.
- The child node values are merged back into the parent node to hold the value for that particular range, [i.e., the range covered by all the nodes of its subtree].
- In the end, leaf nodes store information about a single element. All the leaf nodes store the array based on which the segment tree is built.
Following are the steps for constructing a segment tree:
- Start from the leaves of the tree
- Recursively build the parents from the merge operation
2. Construction Of Segment Tree using Iterative Approach:
- The iterative version of the segment tree basically uses the fact, that for an index i, left child = 2 * i and right child = 2 * i + 1 in the tree.
- The parent for an index i in the segment tree array can be found by parent = i / 2. Thus, we can easily travel up and down through the levels of the tree one by one.
- At first, we compute the maximum in the ranges while constructing the tree starting from the leaf nodes and climbing up through the levels one by one. We use the same concept while processing the queries for finding the maximum in a range.
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:
- P V: Put the value V at position P.
- L R: Query for the values from L to R.
Querying On Segment Tree:
The below table lists the query type and its time complexity for a segment tree:
|
Build a segment tree from an input array of Size n. | O(n)
|
Update the value of an element at a specific index.
| O(log n) - Height of the segment tree.
|
Retrieve information about a specific range in the array (e.g., sum, min, max).
| O(log n) - Height of the segment tree.
|
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.
|
Applications of Segment Trees in Competitive Programming:
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:
- L R: return the sum of the array values from index L to R
- i X: Update the value at index i to X
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:
- L R: return the sum of the array values from index L to R
- L R X: Update the value from index L to R by addingX/subtractingX/square Rooting/etc to them
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:
- L R: Return the min/max value in the range L to R.
- i X: update the value at index i to X
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:
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:
- Interval Intersection:
- To find the intersection of two intervals, you need to consider the overlapping portion of the intervals.
- For a segment tree, this involves traversing the tree and finding the common segments in the nodes
- Interval Union:
- To find the union of two intervals, you need to combine the intervals while ensuring that the union covers both intervals.
- In a segment tree, this involves updating the tree to represent the union of intervals.
- Updates:
- Updates in a segment tree refer to modifying the intervals stored in the tree.
- This can involve changing the value of a specific element or extending/shrinking an interval.
Advanced Topics and Variations for Segment Tree:
Alternative Data Structures for Segment Tree:
Practice Problems on Segment Tree:
Similar Reads
DP on Trees for Competitive Programming
Dynamic Programming (DP) on trees is a powerful algorithmic technique commonly used in competitive programming. It involves solving various tree-related problems by efficiently calculating and storing intermediate results to optimize time complexity. By using the tree structure, DP on trees allows p
15+ min read
Queue for Competitive Programming
In competitive programming, a queue is a data structure that is often used to solve problems that involve tasks that need to be completed in a specific order. This article explores the queue data structure and identifies its role as a critical tool for overcoming coding challenges in competitive pro
8 min read
Stack for Competitive Programming
For competitive programming to be successful, efficient data structures and algorithms are essential. The stack is one such tool. In this article, we will examine how stack data structures play an important role in solving problems efficiently during competitive programming challenges. We will explo
7 min read
Ternary Search for Competitive Programming
Ternary search is a powerful algorithmic technique that plays a crucial role in competitive programming. This article explores the fundamentals of ternary search, idea behind ternary search with its use cases that will help solving complex optimization problems efficiently. Table of Content What is
8 min read
String Guide for Competitive Programming
Strings are a sequence of characters, and are one of the most fundamental data structures in Competitive Programming. String problems are very common in competitive programming contests, and can range from simple to very challenging. In this article we are going to discuss about most frequent string
15 min read
Heap Data Structure for Competitive Programming
Competitive programming needs smart tools to solve problems quickly. One key tool is the Heap Data Structure, which helps organize data in a way that's super fast. In this article, we'll break down the Heap, looking at its types, basic moves, and how it's a big deal in competitive programming. We'll
15+ min read
How to read Competitive Programming Questions?
Competitive Programming is considered as a sport in the field of computer science. The culture of this sport is growing day by day and a lot of people are also considering this as a career choice. So, to help the participants with improving their efficiency in this sport, in this post, we have tried
5 min read
Arrays for Competitive Programming
In this article, we will be discussing Arrays which is one of the most commonly used data structure. It also plays a major part in Competitive Programming. Moreover, we will see built-in methods used to write short codes for array operations that can save some crucial time during contests. Table of
15+ min read
Competitive Programming vs General Programming
Programming enthusiasts face a crossroads - Competitive Programming or General Programming? This article sheds light on the distinctions between Competitive Programming vs General Programming, offering a quick guide for those navigating the coding landscape. Whether you're aiming for speed and preci
3 min read
10 reasons not to quit Competitive Programming
Competitive programming, a sport that combines problem-solving skills with coding expertise has experienced a surge, in popularity recently. As participants navigate through challenges and coding competitions, they acquire a set of skills that go beyond just programming. If you're considering giving
5 min read