Skip to content

Instantly share code, notes, and snippets.

@NamPE286
Last active October 31, 2024 00:34
Show Gist options
  • Save NamPE286/288f57aeaa9459a8cb1d4829c087284d to your computer and use it in GitHub Desktop.
Save NamPE286/288f57aeaa9459a8cb1d4829c087284d to your computer and use it in GitHub Desktop.
Segment tree with lazy propagation implementation with pointer in C++
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
class SegmentTree {
private:
struct Node {
Node* _left;
Node* _right;
pair<ll, ll> range;
ll value = 0, lazy = 0;
Node(ll l, ll r) {
_left = _right = nullptr;
range = {l, r};
}
~Node() {
delete _left;
delete _right;
}
Node* left() {
auto [l, r] = range;
if (l == r) {
return nullptr;
}
return _left = (_left == nullptr ? new Node(l, (l + r) / 2) : _left);
}
Node* right() {
auto [l, r] = range;
if (l == r) {
return nullptr;
}
return _right = (_right == nullptr ? new Node((l + r) / 2 + 1, r) : _right);
}
};
Node* root = nullptr;
void propagate(Node* cur) {
if(cur->lazy == 0) {
return;
}
_update(cur->left(), cur->left()->range.first, cur->left()->range.second, cur->lazy);
_update(cur->right(), cur->right()->range.first, cur->right()->range.second, cur->lazy);
cur->lazy = 0;
}
void _update(Node* cur, ll a, ll b, ll x) {
if(cur == nullptr) {
return;
}
auto [l, r] = cur->range;
if (r < a || b < l) {
return;
}
if (a <= l && r <= b) {
cur->value += (r - l + 1) * x;
cur->lazy += x;
return;
}
propagate(cur);
_update(cur->left(), a, b, x);
_update(cur->right(), a, b, x);
cur->value = cur->left()->value + cur->right()->value;
}
ll _query(Node* cur, ll a, ll b) {
if (cur == nullptr) {
return 0;
}
auto [l, r] = cur->range;
if (r < a || b < l) {
return 0;
}
if (a <= l && r <= b) {
return cur->value;
}
propagate(cur);
return _query(cur->left(), a, b) + _query(cur->right(), a, b);
}
public:
SegmentTree(ll n) {
root = new Node(0, n - 1);
}
~SegmentTree() {
delete root;
}
void update(ll a, ll b, ll x) {
_update(root, a, b, x);
}
ll query(ll a, ll b) {
return _query(root, a, b);
}
};
int main() {
SegmentTree tree(8);
for(ll i = 0; i < 8; i++) {
tree.update(i, i, i + 1);
}
cout << tree.query(1, 6) << '\n'; // 27
tree.update(0, 7, 1);
cout << tree.query(0, 7) << '\n'; // 44
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment