Skip to content

Instantly share code, notes, and snippets.

@buttercrab
Last active October 28, 2019 03:16
Show Gist options
  • Save buttercrab/f0b03d3fab4707801b0881f51c89efd5 to your computer and use it in GitHub Desktop.
Save buttercrab/f0b03d3fab4707801b0881f51c89efd5 to your computer and use it in GitHub Desktop.
segment tree implementation with lazy propagation in c++
#include <bits/stdc++.h>
using namespace std;
int func(int a, int b) {
// binary function
// ex) return gcd(a, b);
// ex) return a * b;
// ex) return a ^ b;
// BUT! associated law has to be held
return a + b;
}
int nest_func(int a, int n) {
// func(a, func(a, func(a, ...))) (n times)
// normally O(1) with some functions
// but you could always do on O(log n)
return a * n;
}
vector<int> seg, lazy;
void init(vector<int> &vec, int node, int left, int right) {
if(left == right) {
seg[node] = vec[left - 1];
return;
}
init(vec, node << 1, left, (left + right) >> 1);
init(vec, node << 1 | 1, ((left + right) >> 1) + 1, right);
seg[node] = func(seg[node << 1], seg[node << 1 | 1]);
}
void busy(int node, int left, int right) {
if(!lazy[node]) return;
seg[node] = func(seg[node], nest_func(lazy[node], (right - left + 1)));
if(left != right) {
lazy[node << 1] = func(lazy[node << 1], lazy[node]);
lazy[node << 1 | 1] = func(lazy[node << 1 | 1], lazy[node]);
}
lazy[node] = 0;
}
void update(int node, int left, int right, int start, int end, int diff) {
busy(node, left, right);
if(right < start || end < left) return;
if(start <= left && right <= end) {
lazy[node] = diff;
busy(node, left, right);
return;
}
update(node << 1, left, (left + right) >> 1, start, end, diff);
update(node << 1 | 1, ((left + right) >> 1) + 1, right, start, end, diff);
seg[node] = func(seg[node << 1], seg[node << 1 | 1]);
}
int query(int node, int left, int right, int start, int end) {
busy(node, left, right);
if(start <= left && right <= end) return seg[node];
int mid = (left + right) >> 1;
if(mid < start) return query(node << 1 | 1, mid + 1, right, start, end);
if(mid + 1 > end) return query(node << 1, left, mid, start, end);
return func(query(node << 1, left, mid, start, end), query(node << 1 | 1, mid + 1, right, start, end));
}
int main() {
int size = 4;
seg.resize(4 * size);
lazy.resize(4 * size);
vector<int> vec{1, 2, 3, 4};
init(vec, 1, 1, size);
update(1, 1, size, 2, 3, 4);
cout << query(1, 1, size, 2, 4) << endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment