Segment Tree
O(log n) per queryPoint updates and range queries over any associative operation (min, max, sum, gcd, ...). This is the compact iterative (bottom-up) version. Swap the two combine lines to change the operation. Reach for it when a Fenwick tree isn't enough (min/max, non-invertible operations).
// use it on
CSES: Dynamic Range Minimum Queries ↗
Point assignments mixed with range-minimum queries. Replace the + combine with min and it's done.
// the code
struct SegTree { // point update, range query on [l, r)
int n;
vector<long long> t;
SegTree(int n) : n(n), t(2 * n, 0) {}
void update(int i, long long v) { // set a[i] = v
for (t[i += n] = v; i > 1; i >>= 1)
t[i >> 1] = t[i] + t[i ^ 1]; // combine
}
long long query(int l, int r) { // fold over [l, r)
long long res = 0; // identity of the combine
for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
if (l & 1) res += t[l++];
if (r & 1) res += t[--r];
}
return res;
}
};// more range queries
