---
tags: Data Structure
title: Segment Tree
---
## Range Minimum (Maximum) Query
```cpp
class SegmentTree {
public:
SegmentTree(size_t size) : N(size), arr(size << 2, 0), tag(size << 2, 0) {}
int query(int left, int right) {
return query(1, 1, N, left, right);
}
void modify(int left, int right, int val) {
modify(1, 1, N, left, right - 1, val);
}
private:
inline int left(int x) { return x << 1; }
inline int right(int x) { return (x << 1) | 1;}
inline void push(int x) {
tag[left(x)] += tag[x];
tag[right(x)] += tag[x];
arr[x] += tag[x];
tag[x] = 0;
}
int query(int x, int L, int R, int ql, int qr) {
if (ql == L && qr == R) {
return arr[x] + tag[x];
}
push(x);
int M = (L + R) >> 1;
if (qr <= M) {
return query(left(x), L, M, ql, qr);
}
else if (ql > M) {
return query(right(x), M + 1, R, ql, qr);
}
else {
return max(query(left(x), L, M, ql, M),
query(right(x), M + 1, R, M + 1, qr));
}
}
void modify(int x, int L, int R, int ml, int mr, int val) {
if (ml == L && mr == R) {
tag[x] += val;
return;
}
int M = (L + R) >> 1;
if (mr <= M) {
modify(left(x), L, M, ml, mr, val);
}
else if (ml > M) {
modify(right(x), M + 1, R, ml, mr, val);
}
else {
modify(left(x), L, M, ml, M, val);
modify(right(x), M + 1, R, M + 1, mr, val);
}
arr[x] = max(arr[left(x)] + tag[left(x)],
arr[right(x)] + tag[right(x)]);
}
size_t N;
vector<int> arr;
vector<int> tag;
};
```
## Range Sum Query
```cpp
class SegmentTree {
public:
SegmentTree(const vector<int>& that)
: N(that.size()), arr(that.size() << 2, 0), tag(that.size() << 2, 0) {
build(1, 1, N, that);
}
void modify(int left, int right, int val) {
modify(1, 1, N, left, right, val);
}
ll query(int left, int right) {
return query(1, 1, N, left, right);
}
private:
inline int left(int x) { return x << 1; }
inline int right(int x) { return (x << 1) | 1;}
ll build(int x, int L, int R, const vector<int>& that) {
if (L == R) {
return arr[x] = that[L - 1];
}
int M = (L + R) >> 1;
return arr[x] = build(left(x), L, M, that) +
build(right(x), M + 1, R, that);
}
inline ll calculate(int x, int L, int R) {
return arr[x] + tag[x] * (R - L + 1);
}
inline void push(int x, int L, int R) {
tag[left(x)] += tag[x];
tag[right(x)] += tag[x];
arr[x] = calculate(x, L, R);
tag[x] = 0;
}
ll query(int x, int L, int R, int ql, int qr) {
if (ql == L && qr == R) {
return calculate(x, L, R);
}
push(x, L, R);
int M = (L + R) >> 1;
if (qr <= M) {
return query(left(x), L, M, ql, qr);
}
else if (ql > M) {
return query(right(x), M + 1, R, ql, qr);
}
else {
return query(left(x), L, M, ql, M) +
query(right(x), M + 1, R, M + 1, qr);
}
}
void modify(int x, int L, int R, int ml, int mr, int val) {
if (ml == L && mr == R) {
tag[x] += val;
return;
}
int M = (L + R) >> 1;
if (mr <= M) {
modify(left(x), L, M, ml, mr, val);
}
else if (ml > M) {
modify(right(x), M + 1, R, ml, mr, val);
}
else {
modify(left(x), L, M, ml, M, val);
modify(right(x), M + 1, R, M + 1, mr, val);
}
arr[x] = calculate(left(x), L, M) + calculate(right(x), M + 1, R);
}
size_t N;
vector<ll> arr;
vector<ll> tag;
};
```