A segment tree is a data structure that supports two operations: processing a complex range query and updating an array value in O(lgn) time. Unlike Binary Indexed Tree which only supports sum queries, a Segment Tree supports other complex queries such as min/max queries. However, segment tree is usually harder to implement and requires more memory.
Structure of the Segment Tree
A segment tree is a binary tree such that the nodes on the bottom level of the tree correspond to the array elements, and the other nodes contain its child information for processing range queries.
We compute and store the sum of the elements of the whole array, i.e. the sum of the segment a[0…n−1] . We then split the array into two halves a[0…n/2−1] and a[n/2…n−1] and compute the sum of each halve and store them. Each of these two halves in turn are split in half, and so on until all segments reach size 1.
Why the size of the array is 4n?
The segment tree is stored as an array of 4n elements where n is the size of original array and a power of two. The first level of the tree contains a single node (the root), the second level will contain two vertices, in the third it will contain four vertices, until the number of vertices reaches n .
Thus the number of vertices in the worst case can be estimated by the sum 1+2+4+⋯+2⌈log2n⌉<2⌈log2n⌉+1<4n .
The height of the Segment Tree is O(logn) , because when going down from the root to the leaves the size of the segments decreases approximately by half.
Implementation
Standard Segment Tree
Lazy Propagation
C++
Complexity
Time complexity: O(lgn) for query and update operations
Space complexity: O(4n), where n is the size of the original array