STL
C++
Segment Tree
Data Structures
Programming

STL for segment tree in C

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

The C++ STL does not include a built-in segment tree container. In practice, people implement segment trees themselves and usually use STL containers such as std::vector to store the tree nodes.

What a segment tree does

A segment tree supports efficient range queries and updates on an array. Typical examples include:

  • range sum
  • range minimum
  • range maximum
  • point update
  • lazy range update in more advanced versions

The main benefit is that both queries and updates can run in O(log n) time.

Why there is no STL segment tree

The STL focuses on broadly reusable containers and algorithms. A segment tree is specialized and problem-dependent because the combine operation, identity value, and update behavior vary a lot.

So the usual answer to "what STL is used for segment tree" is: there is no dedicated STL type, but std::vector is the common storage backing.

A simple segment tree with std::vector

Here is a compact range-sum implementation.

cpp
1#include <iostream>
2#include <vector>
3using namespace std;
4
5class SegmentTree {
6public:
7    SegmentTree(const vector<int>& values) {
8        n = values.size();
9        tree.assign(4 * n, 0);
10        build(1, 0, n - 1, values);
11    }
12
13    int query(int left, int right) {
14        return query(1, 0, n - 1, left, right);
15    }
16
17    void update(int index, int value) {
18        update(1, 0, n - 1, index, value);
19    }
20
21private:
22    int n;
23    vector<int> tree;
24
25    void build(int node, int start, int end, const vector<int>& values) {
26        if (start == end) {
27            tree[node] = values[start];
28            return;
29        }
30
31        int mid = (start + end) / 2;
32        build(node * 2, start, mid, values);
33        build(node * 2 + 1, mid + 1, end, values);
34        tree[node] = tree[node * 2] + tree[node * 2 + 1];
35    }
36
37    int query(int node, int start, int end, int left, int right) {
38        if (right < start || end < left) {
39            return 0;
40        }
41        if (left <= start && end <= right) {
42            return tree[node];
43        }
44
45        int mid = (start + end) / 2;
46        return query(node * 2, start, mid, left, right) +
47               query(node * 2 + 1, mid + 1, end, left, right);
48    }
49
50    void update(int node, int start, int end, int index, int value) {
51        if (start == end) {
52            tree[node] = value;
53            return;
54        }
55
56        int mid = (start + end) / 2;
57        if (index <= mid) {
58            update(node * 2, start, mid, index, value);
59        } else {
60            update(node * 2 + 1, mid + 1, end, index, value);
61        }
62        tree[node] = tree[node * 2] + tree[node * 2 + 1];
63    }
64};

This uses the STL only as support infrastructure. The segment tree logic is custom.

Why std::vector is the usual choice

A segment tree is often stored in an array-like structure where node 1 is the root, 2 * node is the left child, and 2 * node + 1 is the right child. std::vector is perfect for that because it gives:

  • contiguous storage
  • simple indexing
  • dynamic sizing
  • no manual memory management

That is why most competitive programming and interview implementations use vector<int> tree(4 * n) or something similar.

Alternatives worth knowing

If you only need prefix sums and point updates, a Fenwick tree may be simpler and smaller than a segment tree.

If you need a minimum or maximum over a static array with no updates, a sparse table can be better.

So before implementing a segment tree, make sure the problem actually needs one.

Common Pitfalls

The biggest mistake is looking for a ready-made STL segment tree and assuming it must exist because the structure is common in algorithms. It does not.

Another issue is allocating too small a backing array. Using around 4 * n elements is the standard simple choice for recursive implementations.

It is also easy to hardcode range-sum logic and then forget that other query types need different identity values and combine operations.

Finally, recursive segment trees are easy to write but not the only option. Iterative segment trees also exist and can be faster or simpler in some codebases.

Summary

  • The STL does not provide a built-in segment tree container.
  • 'std::vector is the usual storage container for a custom implementation.'
  • Segment trees support O(log n) range queries and updates.
  • Choose the combine operation and identity value based on the actual problem.
  • Consider Fenwick trees or other structures when the problem is simpler than a full segment tree.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.