/// Treap (Cartesian Tree) /// Store x (key) and y (priority) /// Base Functions /// tSplit: split into =x /// tMerge: merge trees l and r if {keys of l} <= {keys of r} /// Set Interface (Multiset) /// tInsert: add x into set /// tFind: test if x is in set /// tRemove: erase one x from set /// 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 *; struct Node { int x; int y; PNode left; PNode right; Node (int x_) { x = x_; y = uniform (gen); left = nullptr; right = nullptr; } }; 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; return {p.first, t}; } else { auto p = tSplit (t -> right, x); t -> right = p.first; 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); return r; } else { l -> right = tMerge (l -> right, r); return l; } } PNode tInsert (PNode t, int x) { auto v = new Node (x); 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; 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); } } bool tFind (PNode t, int x) { if (t == nullptr) return false; if (t -> x == x) return true; 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) return tMerge (t -> left, t -> right); if (t -> x < x) { t -> right = tRemove (t -> right, x); return t; } else { t -> left = tRemove (t -> left, x); 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); 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; }