Last active
October 31, 2024 00:34
-
-
Save NamPE286/288f57aeaa9459a8cb1d4829c087284d to your computer and use it in GitHub Desktop.
Segment tree with lazy propagation implementation with pointer in C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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