Segment Tree


Implementation
Lazy Propogation
Problems
Reference
Last updated


Last updated
merge(merge(a, b), c) = merge(a, merge(b, c))
// Example
max(max(a, b), c) = max(a, max(b, c))
gcd(gcd(a, b), c) = gcd(a, gcd(b, c))// OJ: https://leetcode.com/problems/range-sum-query-mutable/
// Author: github.com/lzl124631x
// Time:
// NumArray: O(N)
// update: O(1)
// sumRange: O(logN)
// Space: O(N)
class NumArray {
vector<int> tree;
int N;
void buildTree(vector<int> &nums) {
for (int i = 0, j = N; i < N;) tree[j++] = nums[i++]; // the input array values are stored in `tree[N...(2 * N - 1)]`
for (int i = N - 1; i > 0; --i) tree[i] = tree[2 * i] + tree[2 * i + 1]; // from `tree[N-1]` to `tree[1]`, build the non-leaf nodes. Note that we don't use `tree[0]`.
}
public:
NumArray(vector<int>& nums) {
if (nums.empty()) return;
N = nums.size();
tree = vector<int>(N * 2);
buildTree(nums); // Segment tree requires initialization.
}
void update(int i, int val) {
i += N; // Offset N to get the leaf node
tree[i] = val;
while (i > 0) {
i /= 2; // Move to the parent node
tree[i] = tree[2 * i] + tree[2 * i + 1]; // Update the parent node
}
}
int sumRange(int i, int j) {
i += N; // Offset N to get the leaf nodes
j += N;
int sum = 0;
while (i <= j) { // When the range is not empty
if (i % 2) sum += tree[i++];
if (j % 2 == 0) sum += tree[j--];
i /= 2;
j /= 2;
}
return sum;
}
};// OJ: https://leetcode.com/problems/range-sum-query-mutable/
// Author: github.com/lzl124631x
// Time:
// NumArray: O(N)
// update: O(1)
// sumRange: O(logN)
// Space: O(N)
typedef int Merge(const int &a, const int& b);
class SegTree {
vector<int> tree;
int N;
Merge *merge;
void buildTree(vector<int> &nums) {
for (int i = 0, j = N; i < N;) tree[j++] = nums[i++];
for (int i = N - 1; i > 0; --i) tree[i] = merge(tree[2 * i], tree[2 * i + 1]);
}
public:
SegTree(vector<int> &nums, Merge merge) {
N = nums.size();
tree.resize(N * 2);
this->merge = merge;
buildTree(nums);
}
void update(int i, int val) {
i += N;
tree[i] = val;
while (i > 0) {
i /= 2;
tree[i] = merge(tree[2 * i], tree[2 * i + 1]);
}
}
int query(int from, int to, int def) {
int i = from + N, j = to + N;
int ans = def;
while (i <= j) {
if (i % 2) ans = merge(ans, tree[i++]);
if (j % 2 == 0) ans = merge(ans, tree[j--]);
i /= 2;
j /= 2;
}
return ans;
}
};
class NumArray {
SegTree* tree;
public:
NumArray(vector<int>& nums) {
if (nums.empty()) return;
tree = new SegTree(nums, [](const int &a, const int &b) { return a + b; });
}
void update(int i, int val) {
tree->update(i, val);
}
int sumRange(int i, int j) {
return tree->query(i, j, 0);
}
};