/// Treap (Cartesian Tree) /// Store x (key) and y (priority) /// Store value /// Maintain size of subtree /// Base Functions /// tSplit: split into =x /// tMerge: merge trees l and r if {keys of l} <= {keys of r} /// Map Interface (Multimap) /// tInsert: add (x, value) pair into map /// tFind: return value for given key x /// tRemove: erase one key x from map /// Debugging /// tOutput: print bracket structure of tree /// tOutput2: print vertical representation /// Example Usage /// Add 10^7 elements /// Find 10^7 elements /// Remove 10^7 elements #include using namespace std; auto gen = mt19937 (); auto uniform = uniform_int_distribution (1, int (1E9)); struct Node; using PNode = Node *; using Num = int; int getSize (PNode t); struct Node { int x; Num value; int y; int size; PNode left; PNode right; void recalc () { // size = 1 + getSize (this -> left) + getSize (this -> right); size = 1 + getSize (left) + getSize (right); } Node (int x_, Num value_) { x = x_; value = value_; y = uniform (gen); size = 1; left = nullptr; right = nullptr; } ~Node () { delete left; delete right; } }; int getSize (PNode t) {return (t == nullptr) ? 0 : t -> size;} pair tSplit (PNode t, int x) { if (t == nullptr) return {nullptr, nullptr}; if (t -> x >= x) { auto p = tSplit (t -> left, x); t -> left = p.second; t -> recalc (); return {p.first, t}; } else { auto p = tSplit (t -> right, x); t -> right = p.first; t -> recalc (); return {t, p.second}; } } PNode tMerge (PNode l, PNode r) { if (l == nullptr) return r; if (r == nullptr) return l; if (l -> y < r -> y) { r -> left = tMerge (l, r -> left); r -> recalc (); return r; } else { l -> right = tMerge (l -> right, r); l -> recalc (); return l; } } PNode tInsert (PNode t, int x, Num value) { auto v = new Node (x, value); auto p = tSplit (t, x); auto half = tMerge (p.first, v); return tMerge (half, p.second); } void tOutput (PNode t, bool doEndl = true) { if (t != nullptr) { cout << '('; tOutput (t -> left, false); cout << t -> x << ':' << t -> value << '|' << t -> size; tOutput (t -> right, false); cout << ')'; } if (doEndl) cout << '.' << endl; } void tOutput2 (PNode t, int depth = 1) { if (t != nullptr) { tOutput2 (t -> left, depth + 1); cout << setw (depth) << ' ' << t -> x << endl; tOutput2 (t -> right, depth + 1); } } Num tFind (PNode t, int x) { if (t == nullptr) return Num (-1); if (t -> x == x) return t -> value; if (t -> x < x) return tFind (t -> right, x); else return tFind (t -> left, x); } PNode tRemove (PNode t, int x) { if (t == nullptr) return t; if (t -> x == x) { auto res = tMerge (t -> left, t -> right); t -> left = nullptr; t -> right = nullptr; delete t; return res; } if (t -> x < x) { t -> right = tRemove (t -> right, x); t -> recalc (); return t; } else { t -> left = tRemove (t -> left, x); t -> recalc (); return t; } } int main () { /* Node u; u.x; u.y; u.left; u.right; PNode v; (*v).x; (*v).y; v -> x; v -> y; */ int const n = int (1E7); PNode root = nullptr; for (int x = 1; x <= n; x++) { root = tInsert (root, x * 2, (x * 1LL * x) % 17); if (x <= 10) {tOutput2 (root); cout << endl;} } for (int x = 1; x <= n; x++) { auto res = tFind (root, x); if (x <= 10) {cout << x << ' ' << res << endl;} } for (int x = 1; x <= n; x++) { root = tRemove (root, x * 2); if (n - x <= 10) tOutput (root); } return 0; }