segment tree
segment tree
Segment Tree is a data structures that allows efficient querying and updating of
intervals or segments of an array.
It is particularly useful for problems involving range queries, such as
finding the sum, minimum, maximum, or any other operation over a
specific range of elements in an array.
The tree is built recursively by dividing the array into segments until each
segment represents a single element.
This structure enables fast query and update operations with a time
complexity of O(log n), making it a powerful tool in algorithm design
and optimization .
Types of Operations:
The operations that the segment tree can perform must be binary and
associative. Some of the examples of operations are:
Finding Range Sum Queries
Searching index with given prefix sum
Finding Range Maximum/Minimum
Counting frequency of Range Maximum/Minimum
Finding Range GCD/LCM
Finding Range AND/OR/XOR
Finding number of zeros in the given range or finding index of Kth zero
A Segment Tree is used to stores information about array intervals in its nodes.
It allows efficient range queries over array intervals.
Along with queries, it allows efficient updates of array items.
For example, we can perform a range summation of an array between the
range L to R in O(Log n) while also modifying any array element in
O(Log n) Time
Types of Operations:
Segment Trees are mainly used for range queries on a fixed sized array. The
values of array elements can be changed. The type of range queries that a
segment tree can perform must have the property that to answer query from L to
R, we can use the answers from L to M and M + 1 to R where M is a point
between L to R, i.e., L <= M <= R.
The following are few example queries over a range in an array.
Addition/Subtraction
Maximum/Minimum
GCD/LCM
AND/OR/XOR
Structure of the 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).
Constructing the 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.
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:
1. Start from the leaves of the tree
2. Recursively build the parents from the merge operation
The merge operation will take constant time if the operator takes constant time.
SO building the whole tree takes O(N) time.
Segment tree
Range Query
Let us understand this with the help of the following problem
Given two integers L and R return the sum of the segment [L, R]
The first step is constructing the segment tree with the addition operator and 0
as the neutral element.
If the range is one of the node’s range values then simply return the
answer.
Otherwise, we will need to traverse the left and right children of the
nodes and recursively continue the process till we find a node that covers
a range that totally covers a part or whole of the range [L, R]
While returning from each call, we need to merge the answers received
from each of its child.
As the height of the segment tree is logN the query time will be O(logN) per
query.