diff --git a/structure/bbst/lazy-reversible-splay-tree.hpp b/structure/bbst/lazy-reversible-splay-tree.hpp index 0750cc8c4..d41c039dd 100644 --- a/structure/bbst/lazy-reversible-splay-tree.hpp +++ b/structure/bbst/lazy-reversible-splay-tree.hpp @@ -1,90 +1,306 @@ /** * @brief Lazy-Reversible-Splay-Tree(遅延伝搬反転可能Splay木) */ -template -struct LazyReversibleSplayTreeNode { - using T = Tp; - using E = Ep; - LazyReversibleSplayTreeNode *l, *r, *p; - T key, sum; - E lazy; - bool rev; - size_t sz; - - LazyReversibleSplayTreeNode() : LazyReversibleSplayTreeNode(Tp()) {} - - LazyReversibleSplayTreeNode(const T &key) - : LazyReversibleSplayTreeNode(key, E()) {} - - LazyReversibleSplayTreeNode(const T &key, const E &lazy) - : key(key), - sum(key), - rev(false), - l(nullptr), - r(nullptr), - p(nullptr), - sz(1), - lazy(lazy) {} -}; - -template -struct LazyReversibleSplayTree : ReversibleSplayTree { - public: +template +struct LazyReversibleSplayTree { public: - using Node = Np; - using T = typename Node::T; - using E = typename Node::E; - using super = ReversibleSplayTree; - using F = typename super::F; - using G = function; - using H = function; - using S = typename super::S; - using NP = typename super::NP; - - explicit LazyReversibleSplayTree(const F &f, const G &g, const H &h, - const S &s, const T &M1, const E &OM0) - : g(g), h(h), OM0(OM0), super(f, s, M1) {} - - using super::merge; - using super::splay; - using super::split; - - NP alloc(const T &x) { return new Node(x, OM0); } - - void push(NP t) override { - if (t->lazy != OM0) { - if (t->l) propagate(t->l, t->lazy); - if (t->r) propagate(t->r, t->lazy); - t->lazy = OM0; + using F = function; + using G = function; + using H = function; + using S = function; + + struct Node { + Node *l, *r, *p; + Monoid key, sum; + OperatorMonoid lazy; + bool rev; + size_t sz; + + bool is_root() const { return !p || (p->l != this && p->r != this); } + + Node(const Monoid &key, const OperatorMonoid &om) + : key(key), + sum(key), + lazy(om), + sz(1), + rev(false), + l(nullptr), + r(nullptr), + p(nullptr) {} + }; + + LazyReversibleSplayTree(const F &f, const Monoid &M1) + : LazyReversibleSplayTree(f, [](const Monoid &a) { return a; }, M1) {} + + LazyReversibleSplayTree(const F &f, const S &s, const Monoid &M1) + : LazyReversibleSplayTree(f, G(), H(), s, M1, OperatorMonoid()) {} + + LazyReversibleSplayTree(const F &f, const G &g, const H &h, const S &s, + const Monoid &M1, const OperatorMonoid &OM0) + : f(f), g(g), h(h), s(s), M1(M1), OM0(OM0) {} + + inline size_t count(const Node *t) { return t ? t->sz : 0; } + + inline const Monoid &sum(const Node *t) { return t ? t->sum : M1; } + + Node *alloc(const Monoid &v = Monoid()) { return new Node(v, OM0); } + + void splay(Node *t) { + push(t); + while (!t->is_root()) { + auto *q = t->p; + if (q->is_root()) { + push(q), push(t); + if (q->l == t) + rotr(t); + else + rotl(t); + } else { + auto *r = q->p; + push(r), push(q), push(t); + if (r->l == q) { + if (q->l == t) + rotr(q), rotr(t); + else + rotl(t), rotr(t); + } else { + if (q->r == t) + rotl(q), rotl(t); + else + rotr(t), rotl(t); + } + } + } + } + + Node *push_front(Node *t, const Monoid &v = Monoid()) { + if (!t) { + t = alloc(v); + return t; + } else { + splay(t); + Node *cur = get_left(t), *z = alloc(v); + splay(cur); + z->p = cur; + cur->l = z; + splay(z); + return z; } - super::push(t); } - NP set_propagate(NP &t, int a, int b, const E &pp) { + Node *push_back(Node *t, const Monoid &v = Monoid()) { + if (!t) { + t = alloc(v); + return t; + } else { + splay(t); + Node *cur = get_right(t), *z = alloc(v); + splay(cur); + z->p = cur; + cur->r = z; + splay(z); + return z; + } + } + + Node *erase(Node *t) { + splay(t); + Node *x = t->l, *y = t->r; + delete t; + if (!x) { + t = y; + if (t) t->p = nullptr; + } else if (!y) { + t = x; + t->p = nullptr; + } else { + x->p = nullptr; + t = get_right(x); + splay(t); + t->r = y; + y->p = t; + } + return t; + } + + Node *get_left(Node *t) const { + while (t->l) t = t->l; + return t; + } + + Node *get_right(Node *t) const { + while (t->r) t = t->r; + return t; + } + + void set_propagate(Node *&t, int a, int b, const OperatorMonoid &pp) { splay(t); auto x = split(t, a); auto y = split(x.second, b - a); set_propagate(y.first, pp); - return t = merge(x.first, y.first, y.second); + t = merge(x.first, y.first, y.second); } - void set_propagate(NP t, const E &pp) { + virtual void set_propagate(Node *&t, const OperatorMonoid &pp) { splay(t); propagate(t, pp); push(t); } + pair split(Node *t, int k) { + if (!t) return {nullptr, nullptr}; + push(t); + if (k <= count(t->l)) { + auto x = split(t->l, k); + t->l = x.second; + t->p = nullptr; + if (x.second) x.second->p = t; + return {x.first, update(t)}; + } else { + auto x = split(t->r, k - count(t->l) - 1); + t->r = x.first; + t->p = nullptr; + if (x.first) x.first->p = t; + return {update(t), x.second}; + } + } + + tuple split3(Node *t, int a, int b) { + splay(t); + auto x = split(t, a); + auto y = split(x.second, b - a); + return make_tuple(x.first, y.first, y.second); + } + + template + Node *merge(Node *l, Args... rest) { + Node *r = merge(rest...); + if (!l && !r) return nullptr; + if (!l) return splay(r), r; + if (!r) return splay(l), l; + splay(l), splay(r); + l = get_right(l); + splay(l); + l->r = r; + r->p = l; + update(l); + return l; + } + + void insert(Node *&t, int k, const Monoid &v) { + splay(t); + auto x = split(t, k); + t = merge(x.first, alloc(v), x.second); + } + + Monoid erase(Node *&t, int k) { + splay(t); + auto x = split(t, k); + auto y = split(x.second, 1); + auto v = y.first->c; + delete y.first; + t = merge(x.first, y.second); + return v; + } + + Monoid query(Node *&t, int a, int b) { + splay(t); + auto x = split(t, a); + auto y = split(x.second, b - a); + auto ret = sum(y.first); + t = merge(x.first, y.first, y.second); + return ret; + } + + Node *build(const vector &v) { return build(0, (int)v.size(), v); } + + void toggle(Node *t) { + swap(t->l, t->r); + t->sum = s(t->sum); + t->rev ^= true; + } + + Node *update(Node *t) { + t->sz = 1; + t->sum = t->key; + if (t->l) t->sz += t->l->sz, t->sum = f(t->l->sum, t->sum); + if (t->r) t->sz += t->r->sz, t->sum = f(t->sum, t->r->sum); + return t; + } + + void push(Node *t) { + if (t->lazy != OM0) { + if (t->l) propagate(t->l, t->lazy); + if (t->r) propagate(t->r, t->lazy); + t->lazy = OM0; + } + if (t->rev) { + if (t->l) toggle(t->l); + if (t->r) toggle(t->r); + t->rev = false; + } + } + + void set_element(Node *&t, int k, const Monoid &x) { + splay(t); + sub_set_element(t, k, x); + } + private: - const E OM0; + const Monoid M1; + const OperatorMonoid OM0; + const F f; const G g; const H h; + const S s; + + Node *build(int l, int r, const vector &v) { + if (l + 1 >= r) return alloc(v[l]); + return merge(build(l, (l + r) >> 1, v), build((l + r) >> 1, r, v)); + } - void propagate(NP t, const E &x) { + void propagate(Node *t, const OperatorMonoid &x) { t->lazy = h(t->lazy, x); t->key = g(t->key, x); t->sum = g(t->sum, x); } -}; -template -using LRST = LazyReversibleSplayTree >; + void rotr(Node *t) { + auto *x = t->p, *y = x->p; + if ((x->l = t->r)) t->r->p = x; + t->r = x, x->p = t; + update(x), update(t); + if ((t->p = y)) { + if (y->l == x) y->l = t; + if (y->r == x) y->r = t; + update(y); + } + } + + void rotl(Node *t) { + auto *x = t->p, *y = x->p; + if ((x->r = t->l)) t->l->p = x; + t->l = x, x->p = t; + update(x), update(t); + if ((t->p = y)) { + if (y->l == x) y->l = t; + if (y->r == x) y->r = t; + update(y); + } + } + + Node *merge(Node *l) { return l; } + + Node *sub_set_element(Node *&t, int k, const Monoid &x) { + push(t); + if (k < count(t->l)) { + return sub_set_element(t->l, k, x); + } else if (k == count(t->l)) { + t->key = x; + splay(t); + return t; + } else { + return sub_set_element(t->r, k - count(t->l) - 1, x); + } + } +}; diff --git a/structure/bbst/reversible-splay-tree.hpp b/structure/bbst/reversible-splay-tree.hpp index a85a4287e..b334638c8 100644 --- a/structure/bbst/reversible-splay-tree.hpp +++ b/structure/bbst/reversible-splay-tree.hpp @@ -1,51 +1,180 @@ /** * @brief Reversible-Splay-Tree(反転可能Splay木) */ -template -struct ReversibleSplayTreeNode { - using T = Tp; - ReversibleSplayTreeNode *l, *r, *p; - T key, sum; - bool rev; - size_t sz; - - ReversibleSplayTreeNode() : ReversibleSplayTreeNode(Tp()) {} - - ReversibleSplayTreeNode(const T &key) - : key(key), - sum(key), - rev(false), - l(nullptr), - r(nullptr), - p(nullptr), - sz(1) {} -}; - -template -struct ReversibleSplayTree : SplayTreeBase { +template +struct ReversibleSplayTree { public: - using Node = Np; - using T = typename Node::T; - using F = function; - using S = function; - using super = SplayTreeBase; - using NP = typename super::NP; - - explicit ReversibleSplayTree(const F &f, const S &s, const T &M1) + using F = function; + using S = function; + + struct Node { + Node *l, *r, *p; + Monoid key, sum; + bool rev; + size_t sz; + + bool is_root() const { return !p || (p->l != this && p->r != this); } + + Node(const Monoid &key) + : key(key), + sum(key), + sz(1), + rev(false), + l(nullptr), + r(nullptr), + p(nullptr) {} + }; + + ReversibleSplayTree(const F &f, const Monoid &M1) + : ReversibleSplayTree(f, [](const Monoid &a) { return a; }, M1) {} + + ReversibleSplayTree(const F &f, const S &s, const Monoid &M1) : f(f), s(s), M1(M1) {} - using super::build_node; - using super::count; - using super::insert_node; - using super::merge; - using super::splay; - using super::split; + inline size_t count(const Node *t) { return t ? t->sz : 0; } + + inline const Monoid &sum(const Node *t) { return t ? t->sum : M1; } + + Node *alloc(const Monoid &v = Monoid()) { return new Node(v); } + + void splay(Node *t) { + push(t); + while (!t->is_root()) { + auto *q = t->p; + if (q->is_root()) { + push(q), push(t); + if (q->l == t) + rotr(t); + else + rotl(t); + } else { + auto *r = q->p; + push(r), push(q), push(t); + if (r->l == q) { + if (q->l == t) + rotr(q), rotr(t); + else + rotl(t), rotr(t); + } else { + if (q->r == t) + rotl(q), rotl(t); + else + rotr(t), rotl(t); + } + } + } + } + + Node *push_front(Node *t, const Monoid &v = Monoid()) { + if (!t) { + t = alloc(v); + return t; + } else { + splay(t); + Node *cur = get_left(t), *z = alloc(v); + splay(cur); + z->p = cur; + cur->l = z; + splay(z); + return z; + } + } + + Node *push_back(Node *t, const Monoid &v = Monoid()) { + if (!t) { + t = alloc(v); + return t; + } else { + splay(t); + Node *cur = get_right(t), *z = alloc(v); + splay(cur); + z->p = cur; + cur->r = z; + splay(z); + return z; + } + } + + Node *erase(Node *t) { + splay(t); + Node *x = t->l, *y = t->r; + delete t; + if (!x) { + t = y; + if (t) t->p = nullptr; + } else if (!y) { + t = x; + t->p = nullptr; + } else { + x->p = nullptr; + t = get_right(x); + splay(t); + t->r = y; + y->p = t; + } + return t; + } + + Node *get_left(Node *t) const { + while (t->l) t = t->l; + return t; + } + + Node *get_right(Node *t) const { + while (t->r) t = t->r; + return t; + } + + pair split(Node *t, int k) { + if (!t) return {nullptr, nullptr}; + push(t); + if (k <= count(t->l)) { + auto x = split(t->l, k); + t->l = x.second; + t->p = nullptr; + if (x.second) x.second->p = t; + return {x.first, update(t)}; + } else { + auto x = split(t->r, k - count(t->l) - 1); + t->r = x.first; + t->p = nullptr; + if (x.first) x.first->p = t; + return {update(t), x.second}; + } + } + + template + Node *merge(Node *l, Args... rest) { + Node *r = merge(rest...); + if (!l && !r) return nullptr; + if (!l) return splay(r), r; + if (!r) return splay(l), l; + splay(l), splay(r); + l = get_right(l); + splay(l); + l->r = r; + r->p = l; + update(l); + return l; + } - inline const T &sum(const NP t) { return t ? t->sum : M1; } + void insert(Node *&t, int k, const Monoid &v) { + splay(t); + auto x = split(t, k); + t = merge(merge(x.first, alloc(v)), x.second); + } - NP alloc(const T &x) { return new Node(x); } + Monoid erase(Node *&t, int k) { + splay(t); + auto x = split(t, k); + auto y = split(x.second, 1); + auto v = y.first->c; + delete y.first; + t = merge(x.first, y.second); + return v; + } - T query(NP &t, int a, int b) { + Monoid query(Node *&t, int a, int b) { splay(t); auto x = split(t, a); auto y = split(x.second, b - a); @@ -54,19 +183,15 @@ struct ReversibleSplayTree : SplayTreeBase { return ret; } - NP build(const vector &v) { - vector vs(v.size()); - for (int i = 0; i < v.size(); i++) vs[i] = alloc(v[i]); - return build_node(vs); - } + Node *build(const vector &v) { return build(0, (int)v.size(), v); } - void toggle(NP t) { + void toggle(Node *t) { swap(t->l, t->r); t->sum = s(t->sum); t->rev ^= true; } - NP update(NP t) override { + Node *update(Node *t) { t->sz = 1; t->sum = t->key; if (t->l) t->sz += t->l->sz, t->sum = f(t->l->sum, t->sum); @@ -74,7 +199,14 @@ struct ReversibleSplayTree : SplayTreeBase { return t; } - void push(NP t) override { + tuple split3(Node *t, int a, int b) { + splay(t); + auto x = split(t, a); + auto y = split(x.second, b - a); + return make_tuple(x.first, y.first, y.second); + } + + void push(Node *t) { if (t->rev) { if (t->l) toggle(t->l); if (t->r) toggle(t->r); @@ -82,49 +214,57 @@ struct ReversibleSplayTree : SplayTreeBase { } } - NP insert(NP t, int k, const T &x) { return insert_node(t, k, alloc(x)); } - - NP set_element(NP t, int k, const T &x) { + void set_element(Node *&t, int k, const Monoid &x) { splay(t); - return imp_set_element(t, k, x); - } - - pair split_lower_bound(NP t, const T &key) { - if (!t) return {nullptr, nullptr}; - push(t); - if (key <= t->key) { - auto x = split_lower_bound(t->l, key); - t->l = x.second; - t->p = nullptr; - if (x.second) x.second->p = t; - return {x.first, update(t)}; - } else { - auto x = split_lower_bound(t->r, key); - t->r = x.first; - t->p = nullptr; - if (x.first) x.first->p = t; - return {update(t), x.second}; - } + sub_set_element(t, k, x); } private: - const T M1; + const Monoid M1; const F f; const S s; - NP imp_set_element(NP t, int k, const T &x) { + Node *build(int l, int r, const vector &v) { + if (l + 1 >= r) return alloc(v[l]); + return merge(build(l, (l + r) >> 1, v), build((l + r) >> 1, r, v)); + } + + Node *sub_set_element(Node *&t, int k, const Monoid &x) { push(t); if (k < count(t->l)) { - return imp_set_element(t->l, k, x); + return sub_set_element(t->l, k, x); } else if (k == count(t->l)) { t->key = x; splay(t); return t; } else { - return imp_set_element(t->r, k - count(t->l) - 1, x); + return sub_set_element(t->r, k - count(t->l) - 1, x); } } -}; -template -using RST = ReversibleSplayTree >; + void rotr(Node *t) { + auto *x = t->p, *y = x->p; + if ((x->l = t->r)) t->r->p = x; + t->r = x, x->p = t; + update(x), update(t); + if ((t->p = y)) { + if (y->l == x) y->l = t; + if (y->r == x) y->r = t; + update(y); + } + } + + void rotl(Node *t) { + auto *x = t->p, *y = x->p; + if ((x->r = t->l)) t->l->p = x; + t->l = x, x->p = t; + update(x), update(t); + if ((t->p = y)) { + if (y->l == x) y->l = t; + if (y->r == x) y->r = t; + update(y); + } + } + + Node *merge(Node *l) { return l; } +}; diff --git a/structure/bbst/splay-tree-base.hpp b/structure/bbst/splay-tree-base.hpp deleted file mode 100644 index 76a28fa4f..000000000 --- a/structure/bbst/splay-tree-base.hpp +++ /dev/null @@ -1,169 +0,0 @@ -/** - * @brief Splay-Tree-Base(Splay木) - */ -template -struct SplayTreeBase { - public: - using NP = Node *; - - bool is_root(const NP &t) const { - return !t->p || (t->p->l != t && t->p->r != t); - } - - inline size_t count(const NP &t) const { return t ? t->sz : 0; } - - void splay(NP t) { - push(t); - while (!is_root(t)) { - auto *q = t->p; - if (!is_root(t)) { - push(q), push(t); - if (q->l == t) - rotr(t); - else - rotl(t); - } else { - auto *r = q->p; - push(r), push(q), push(t); - if (r->l == q) { - if (q->l == t) - rotr(q), rotr(t); - else - rotl(t), rotr(t); - } else { - if (q->r == t) - rotl(q), rotl(t); - else - rotr(t), rotl(t); - } - } - } - } - - NP erase(NP t) { - splay(t); - Node *x = t->l, *y = t->r; - delete t; - if (!x) { - t = y; - if (t) t->p = nullptr; - } else if (!y) { - t = x; - t->p = nullptr; - } else { - x->p = nullptr; - t = get_right(x); - splay(t); - t->r = y; - y->p = t; - } - return t; - } - - NP splay_front(NP t) { - splay(t); - while (t->l) t = t->l; - splay(t); - return t; - } - - NP splay_back(NP t) { - splay(t); - while (t->r) t = t->r; - splay(t); - return t; - } - - pair split(NP t, int k) { - if (!t) return {nullptr, nullptr}; - push(t); - if (k <= count(t->l)) { - auto x = split(t->l, k); - t->l = x.second; - t->p = nullptr; - if (x.second) x.second->p = t; - return {x.first, update(t)}; - } else { - auto x = split(t->r, k - count(t->l) - 1); - t->r = x.first; - t->p = nullptr; - if (x.first) x.first->p = t; - return {update(t), x.second}; - } - } - - template - NP merge(NP p, Args... args) { - return merge(p, merge(args...)); - } - - NP merge(NP l, NP r) { - if (!l && !r) return nullptr; - if (!l) return splay(r), r; - if (!r) return splay(l), l; - splay(l), splay(r); - l = splay_back(l); - l->r = r; - r->p = l; - update(l); - return l; - } - - tuple split3(NP t, int a, int b) { - splay(t); - auto x = split(t, a); - auto y = split(x.second, b - a); - return make_tuple(x.first, y.first, y.second); - } - - virtual void push(NP t) = 0; - - virtual Node *update(NP t) = 0; - - private: - void rotr(NP t) { - auto *x = t->p, *y = x->p; - if ((x->l = t->r)) t->r->p = x; - t->r = x, x->p = t; - update(x), update(t); - if ((t->p = y)) { - if (y->l == x) y->l = t; - if (y->r == x) y->r = t; - update(y); - } - } - - void rotl(NP t) { - auto *x = t->p, *y = x->p; - if ((x->r = t->l)) t->l->p = x; - t->l = x, x->p = t; - update(x), update(t); - if ((t->p = y)) { - if (y->l == x) y->l = t; - if (y->r == x) y->r = t; - update(y); - } - } - - NP build(int l, int r, const vector &v) { - if (l + 1 >= r) return v[l]; - return merge(build(l, (l + r) >> 1, v), build((l + r) >> 1, r, v)); - } - - protected: - NP build_node(const vector &v) { return build(0, v.size(), v); } - - NP insert_node(NP t, int k, NP v) { - splay(t); - auto x = split(t, k); - return merge(x.first, v, x.second); - } - - NP erase_node(NP t, int k) { - splay(t); - auto x = split(t, k); - auto y = split(x.second, 1); - delete y.first; - return merge(x.first, y.second); - } -};