#include #include #include #include #include using namespace std; mt19937 gen(time(0)); int fr(int limit) { return uniform_int_distribution(0, limit-1)(gen); } struct Treap { int x; int sz; bool rev; Treap* left; Treap* right; Treap (int x_) : x(x_), sz(1), rev(false), left(nullptr), right(nullptr) { } }; typedef Treap* Node; int get_sz (Node t) { if (t == nullptr) {return 0;} return t->sz; } void sz_recalc (Node t) { if (t == nullptr) return; t->sz = get_sz (t->left) + get_sz (t->right) + 1; } void push_rev (Node t) { if (!t->rev) return; swap (t->left, t->right); if (t->left != nullptr) t->left->rev ^= t->rev; if (t->right != nullptr) t->right->rev ^= t->rev; t->rev = false; } Node treap_merge (Node t1, Node t2) { if (t1 == nullptr) return t2; if (t2 == nullptr) return t1; push_rev (t1); push_rev (t2); if (fr (t1->sz + t2->sz) < t1->sz) { // t1 is selected root t1->right = treap_merge (t1->right, t2); sz_recalc (t1); return t1; } // t2 is selected root t2->left = treap_merge (t1, t2->left); sz_recalc (t2); return t2; } void treap_print (Node t) { if (t == nullptr) return; push_rev(t); cout << "["; treap_print (t->left); cout << " (" << t->x << ", " << t->sz << ") "; treap_print (t->right); cout << "]"; } pair treap_split_k (Node t, int k) { if (t == nullptr) return {nullptr, nullptr}; push_rev (t); if (k <= get_sz (t->left)) { auto p = treap_split_k (t->left, k); t->left = p.second; sz_recalc (t); return {p.first, t}; } auto p = treap_split_k (t->right, k - get_sz(t->left) - 1); t->right = p.first; sz_recalc (t); return {t, p.second}; } Node treap_insert_k (Node t0, int k, int x0) { Node t = new Treap (x0); if (t0 == nullptr) return t; push_rev(t0); auto p = treap_split_k (t0, k); return treap_merge( p.first, treap_merge (t, p.second) ); } Node set_rev (Node t, int lo, int hi) { auto p_hi = treap_split_k (t, hi); auto p_lo = treap_split_k (p_hi.first, lo); if (p_lo.second != nullptr) p_lo.second->rev ^= true; return treap_merge(treap_merge(p_lo.first, p_lo.second), p_hi.second); } int depth (Node t) { if (t == nullptr) return 0; return max (depth (t->left), depth (t->right)) + 1; } int main ( ) { Node t0 = new Treap (0); for (int i=1; i<13; i++) t0 = treap_insert_k (t0, t0->sz, i); treap_print(t0); cout << endl; Node t1 = set_rev (t0, 4, 8); treap_print(t1); cout << endl; return 0; }