diff --git a/S2OJ/99/99.cpp b/S2OJ/99/99.cpp index 727f109a..38fd37d6 100644 --- a/S2OJ/99/99.cpp +++ b/S2OJ/99/99.cpp @@ -7,11 +7,30 @@ using std::cout; const int N = 100005; -// Treap -void insert(int); -void erase(int); -int getRank(int); -int getKth(int); +class Treap { + private: + int root, cnt; + + struct node { + int l, r, s, v, k; + + node(); + node(int); + } tr[N]; + + void pushup(int); + std::pair split(int, int); + std::pair splitByValue(int, int); + int merge(int, int); + int find(int, int); + int _getRank(int, int); + + public: + void insert(int); + void erase(int); + int getRank(int); + int getKth(int); +} tree; int n, op, x; @@ -21,17 +40,17 @@ int main() { while (n--) { cin >> op >> x; if (op == 1) { - insert(x); + tree.insert(x); } else if (op == 2) { - erase(x); + tree.erase(x); } else if (op == 3) { - cout << getRank(x) << endl; + cout << tree.getRank(x) << endl; } else if (op == 4) { - cout << getKth(x) << endl; + cout << tree.getKth(x) << endl; } else if (op == 5) { - cout << getKth(getRank(x) - 1) << endl; + cout << tree.getKth(tree.getRank(x) - 1) << endl; } else { - cout << getKth(getRank(x + 1)) << endl; + cout << tree.getKth(tree.getRank(x + 1)) << endl; } } return 0; @@ -39,104 +58,102 @@ int main() { // === Treap === -int root, cnt; +// struct Treap::node -struct node { - int l, r, s, v, k; +Treap::node::node() + : l(0), r(0), s(0), v(0), k(rand()) {} +Treap::node::node(int _v) + : l(0), r(0), s(1), v(_v), k(rand()) {} - node() - : l(0), r(0), s(0), v(0), k(rand()) {} - node(int _v) - : l(0), r(0), s(1), v(_v), k(rand()) {} -} tr[N]; +// class Treap -inline void pushup(int u) { - tr[u].s = tr[tr[u].l].s + tr[tr[u].r].s + 1; +inline void Treap::pushup(int u) { + this->tr[u].s = this->tr[this->tr[u].l].s + this->tr[this->tr[u].r].s + 1; } -std::pair split(int p, int k) { +std::pair Treap::split(int p, int k) { if (!p) return std::make_pair(0, 0); - if (k <= tr[tr[p].l].s) { - auto o = split(tr[p].l, k); - tr[p].l = o.second; - pushup(p); + if (k <= this->tr[this->tr[p].l].s) { + auto o = this->split(this->tr[p].l, k); + this->tr[p].l = o.second; + this->pushup(p); o.second = p; return o; } - auto o = split(tr[p].r, k - tr[tr[p].l].s - 1); - tr[p].r = o.first; - pushup(p); + auto o = this->split(this->tr[p].r, k - this->tr[this->tr[p].l].s - 1); + this->tr[p].r = o.first; + this->pushup(p); o.first = p; return o; } -std::pair splitByValue(int p, int v) { +std::pair Treap::splitByValue(int p, int v) { if (!p) return std::make_pair(0, 0); - if (tr[p].v < v) { - auto o = splitByValue(tr[p].r, v); - tr[p].r = o.first; - pushup(p); + if (this->tr[p].v < v) { + auto o = this->splitByValue(tr[p].r, v); + this->tr[p].r = o.first; + this->pushup(p); o.first = p; return o; } - auto o = splitByValue(tr[p].l, v); - tr[p].l = o.second; - pushup(p); + auto o = splitByValue(this->tr[p].l, v); + this->tr[p].l = o.second; + this->pushup(p); o.second = p; return o; } -int merge(int x, int y) { +int Treap::merge(int x, int y) { if (!x) return y; if (!y) return x; - if (tr[x].k > tr[y].k) { - tr[x].r = merge(tr[x].r, y); - pushup(x); + if (this->tr[x].k > this->tr[y].k) { + this->tr[x].r = merge(this->tr[x].r, y); + this->pushup(x); return x; } - tr[y].l = merge(x, tr[y].l); - pushup(y); + this->tr[y].l = merge(x, this->tr[y].l); + this->pushup(y); return y; } -int find(int p, int v) { +int Treap::find(int p, int v) { if (!p) return 0; - if (tr[p].v == v) return p; - if (tr[p].v > v) return find(tr[p].l, v); - return find(tr[p].r, v); + if (this->tr[p].v == v) return p; + if (this->tr[p].v > v) return this->find(this->tr[p].l, v); + return this->find(this->tr[p].r, v); } -void insert(int v) { - auto o = splitByValue(root, v); - int p = ++cnt; - tr[p] = node(v); - o.first = merge(o.first, p); - root = merge(o.first, o.second); +void Treap::insert(int v) { + auto o = this->splitByValue(root, v); + int p = ++this->cnt; + this->tr[p] = Treap::node(v); + o.first = this->merge(o.first, p); + this->root = this->merge(o.first, o.second); } -void erase(int v) { - auto o = splitByValue(root, v); +void Treap::erase(int v) { + auto o = this->splitByValue(root, v); auto t = o; - if (find(o.second, v)) { - t = split(o.second, 1); + if (this->find(o.second, v)) { + t = this->split(o.second, 1); } - root = merge(o.first, t.second); + this->root = this->merge(o.first, t.second); } -int _getRank(int p, int v) { +int Treap::_getRank(int p, int v) { if (!p) return 1; - if (v <= tr[p].v) return _getRank(tr[p].l, v); - return tr[tr[p].l].s + 1 + _getRank(tr[p].r, v); + if (v <= this->tr[p].v) return this->_getRank(this->tr[p].l, v); + return this->tr[this->tr[p].l].s + 1 + this->_getRank(this->tr[p].r, v); } -inline int getRank(int v) { - return _getRank(root, v); +inline int Treap::getRank(int v) { + return this->_getRank(root, v); } -int getKth(int k) { - auto x = split(root, k - 1); - auto y = split(x.second, 1); +int Treap::getKth(int k) { + auto x = this->split(this->root, k - 1); + auto y = this->split(x.second, 1); int o = y.first; - root = merge(x.first, merge(y.first, y.second)); + this->root = this->merge(x.first, this->merge(y.first, y.second)); return tr[o].v; }