#include #include #include using namespace std; struct Treap { int x; int y; int sz; Treap* left; Treap* right; Treap (int x_, int y_) : x(x_), y(y_), sz(1), left(nullptr), right(nullptr) { } }; typedef Treap* Node; int get_sz (Node t) { if (t == nullptr) {return 0;} return t->sz; } /* Size recalculation can not be done by just subtracting / adding smth to the current size, a separate function is needed. */ void sz_recalc (Node t) { if (t == nullptr) return; t->sz = get_sz (t->left) + get_sz (t->right) + 1; } Node treap_merge (Node t1, Node t2) { if (t1 == nullptr) return t2; if (t2 == nullptr) return t1; if (t1->y > t2->y) { t1->right = treap_merge (t1->right, t2); sz_recalc (t1); return t1; } t2->left = treap_merge (t1, t2->left); sz_recalc (t2); return t2; } pair treap_split (Node t, int x0) { // It is guaranteed that all x's are different if (t == nullptr) return {nullptr, nullptr}; if (x0 < t->x) { auto p = treap_split (t->left, x0); t->left = p.second; sz_recalc (t); return {p.first, t}; } auto p = treap_split (t->right, x0); t->right = p.first; sz_recalc (t); return {t, p.second}; } void treap_print (Node t) { if (t==nullptr) return; cout << "["; treap_print (t->left); cout << " (" << t->x << ", " << t->y << ", " << t->sz << ") "; treap_print (t->right); cout << "]"; } Node treap_insert (Node t0, int x0, int y0) { auto p = treap_split (t0, x0); Node t = new Treap (x0, y0); return treap_merge( p.first, treap_merge (t, p.second) ); } Node treap_find_k (Node t, int k) { if (t == nullptr) return nullptr; if (k == get_sz (t->left)) return t; if (k < get_sz (t->left)) return treap_find_k (t->left, k); return treap_find_k (t->right, k - get_sz (t->left) - 1); } pair treap_split_k (Node t, int k) { if (t == nullptr) return {nullptr, nullptr}; 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}; } int main ( ) { Node t0 = new Treap (14, 6); vector > v = { {6, 5}, {16, 4}, {8, 1}, {12, 3}, {0, 2}, {10, 9}, {4, 8}, {18, 7} }; for (auto p : v) t0 = treap_insert (t0, p.first, p.second); treap_print (t0); cout << endl; auto p = treap_split_k (t0, 6); treap_print (p.first); cout << endl; treap_print(p.second); return 0; }