From c38fb4c9f4d32dc08e2ff9d104a2c496bde681a4 Mon Sep 17 00:00:00 2001 From: Ren Baoshuo Date: Wed, 13 Jul 2022 11:24:31 +0800 Subject: [PATCH] =?UTF-8?q?P2596=20[ZJOI2006]=E4=B9=A6=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://www.luogu.com.cn/record/79350717 --- Luogu/P2596/P2596.cpp | 215 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 Luogu/P2596/P2596.cpp diff --git a/Luogu/P2596/P2596.cpp b/Luogu/P2596/P2596.cpp new file mode 100644 index 00000000..cd075f8c --- /dev/null +++ b/Luogu/P2596/P2596.cpp @@ -0,0 +1,215 @@ +#include +#include +#include + +using std::cin; +using std::cout; +const char endl = '\n'; + +const int N = 8e4 + 5; + +struct node { + node *lchild, *rchild, *fa; + std::size_t size; + int value, key; + + node() + : lchild(nullptr), rchild(nullptr), fa(nullptr), size(0), value(0), key(rand()) {} + + node(int _value) + : lchild(nullptr), rchild(nullptr), fa(nullptr), size(1), value(_value), key(rand()) {} + + ~node() { + if (lchild != nullptr) delete lchild; + if (rchild != nullptr) delete rchild; + } + + inline std::size_t lsize() { + return lchild == nullptr ? 0 : lchild->size; + } + + inline std::size_t rsize() { + return rchild == nullptr ? 0 : rchild->size; + } + + inline void pushup() { + size = 1; + + if (lchild != nullptr) { + size += lchild->size; + lchild->fa = this; + } + + if (rchild != nullptr) { + size += rchild->size; + rchild->fa = this; + } + } + + inline std::size_t pos() { + std::size_t ret = lsize() + 1; + node *cur = this; + + while (cur->fa != nullptr) { + if (cur->fa->rchild == cur) { + ret += cur->fa->lsize() + 1; + } + + cur = cur->fa; + } + + return ret; + } +}; + +int n, m; +node *root, *p[N]; + +std::pair split(node *u, int k) { + if (u == nullptr) return std::make_pair(nullptr, nullptr); + + if (k <= u->lsize()) { + auto o = split(u->lchild, k); + + u->lchild = o.second; + u->pushup(); + o.second = u; + + return o; + } + + auto o = split(u->rchild, k - u->lsize() - 1); + + u->rchild = o.first; + u->pushup(); + o.first = u; + + return o; +} + +template +node *merge(node *x, Args... args) { + return merge(x, merge(args...)); +} + +template <> +node *merge(node *x, node *y) { + if (x == nullptr) return y; + if (y == nullptr) return x; + + if (x->key < y->key) { + x->rchild = merge(x->rchild, y); + x->pushup(); + + return x; + } + + y->lchild = merge(x, y->lchild); + y->pushup(); + + return y; +} + +inline void top(const int &x) { + int k = p[x]->pos(); + + auto p = split(root, k - 1); + auto q = split(p.second, 1); + + root = merge(q.first, p.first, q.second); +} + +inline void bottom(const int &x) { + int k = p[x]->pos(); + + auto p = split(root, k - 1); + auto q = split(p.second, 1); + + root = merge(p.first, q.second, q.first); +} + +inline void insert(const int &x, const int &y) { + if (!y) return; + + int k = p[x]->pos(); + auto p = split(root, k - 1); + auto q = split(p.second, 1); + + if (y > 0) { + auto t = split(q.second, y); + root = merge(p.first, t.first, q.first, t.second); + } else { // y < 0 + auto t = split(p.first, k + y - 1); + root = merge(t.first, q.first, t.second, q.second); + } +} + +inline int ask(const int &x) { + return p[x]->pos() - 1; +} + +inline int query(const int &x) { + auto p = split(root, x - 1); + auto q = split(p.second, 1); + + int res = q.first->value; + + root = merge(p.first, q.first, q.second); + + return res; +} + +int main() { + std::ios::sync_with_stdio(false); + cin.tie(nullptr); + + cin >> n >> m; + + for (int i = 1, x; i <= n; i++) { + cin >> x; + + root = merge(root, p[x] = new node(x)); + } + + while (m--) { + std::string op; + int s, t; + + cin >> op >> s; + + switch (op[0]) { + case 'T': { // op == "Top" + top(s); + + break; + } + case 'B': { // op == "Bottom" + bottom(s); + + break; + } + case 'I': { // op == "Insert" + cin >> t; + + insert(s, t); + + break; + } + case 'A': { // op == "Ask" + cout << ask(s) << endl; + + break; + } + case 'Q': { // op == "Query" + cout << query(s) << endl; + + break; + } + } + } + + // Cleanup + delete root; + + return 0; +}