summaryrefslogtreecommitdiff
path: root/datastructures/treap2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'datastructures/treap2.cpp')
-rw-r--r--datastructures/treap2.cpp78
1 files changed, 78 insertions, 0 deletions
diff --git a/datastructures/treap2.cpp b/datastructures/treap2.cpp
new file mode 100644
index 0000000..e0c32a6
--- /dev/null
+++ b/datastructures/treap2.cpp
@@ -0,0 +1,78 @@
+mt19937 rng(0xc4bd5dad);
+struct Treap {
+ struct Node {
+ ll val;
+ int prio, sz = 1, l = -1, r = -1;
+ Node (ll x) : val(x), prio(rng()) {}
+ };
+
+ vector<Node> treap;
+ int root = -1;
+
+ int getSize(int v) {
+ return v < 0 ? 0 : treap[v].sz;
+ }
+
+ void upd(int v) {
+ if (v < 0) return;
+ auto *V = &treap[v];
+ V->sz = 1 + getSize(V->l) + getSize(V->r);
+ // Update Node Code
+ }
+
+ void push(int v) {
+ if (v < 0) return;
+ //auto *V = &treap[v];
+ //if (V->lazy) {
+ // Lazy Propagation Code
+ // if (V->l >= 0) treap[V->l].lazy = true;
+ // if (V->r >= 0) treap[V->r].lazy = true;
+ // V->lazy = false;
+ //}
+ }
+
+ pair<int, int> split(int v, int k) {
+ if (v < 0) return {-1, -1};
+ auto *V = &treap[v];
+ push(v);
+ if (getSize(V->l) >= k) { // "V->val >= k" for lower_bound(k)
+ auto [left, right] = split(V->l, k);
+ V->l = right;
+ upd(v);
+ return {left, v};
+ } else {
+ auto [left, right] = split(V->r, k - getSize(V->l) - 1); // and only "k"
+ V->r = left;
+ upd(v);
+ return {v, right};
+ }}
+
+ int merge(int left, int right) {
+ if (left < 0) return right;
+ if (right < 0) return left;
+ if (treap[left].prio < treap[right].prio) {
+ push(left);
+ treap[left].r = merge(treap[left].r, right);
+ upd(left);
+ return left;
+ } else {
+ push(right);
+ treap[right].l = merge(left, treap[right].l);
+ upd(right);
+ return right;
+ }}
+
+ void insert(int i, ll val) { // and i = val
+ auto [left, right] = split(root, i);
+ treap.emplace_back(val);
+ left = merge(left, sz(treap) - 1);
+ root = merge(left, right);
+ }
+
+ void remove(int i, int count = 1) {
+ auto [left, t_right] = split(root, i);
+ auto [middle, right] = split(t_right, count);
+ root = merge(left, right);
+ }
+ // for query use remove and read middle BEFORE remerging
+};