反転可能平衡二分木(基底クラス)
(lct/reversible-bbst-base.hpp)
Required by
Verified with
Code
#pragma once
template <typename Tree, typename Node, typename T, T (*f)(T, T), T (*ts)(T)>
struct ReversibleBBST : Tree {
using Tree::merge;
using Tree::split;
using typename Tree::Ptr;
ReversibleBBST() = default;
virtual void toggle(Ptr t) {
if(!t) return;
swap(t->l, t->r);
t->sum = ts(t->sum);
t->rev ^= true;
}
T fold(Ptr &t, int a, int b) {
auto x = split(t, a);
auto y = split(x.second, b - a);
auto ret = sum(y.first);
t = merge(x.first, merge(y.first, y.second));
return ret;
}
void reverse(Ptr &t, int a, int b) {
auto x = split(t, a);
auto y = split(x.second, b - a);
toggle(y.first);
t = merge(x.first, merge(y.first, y.second));
}
Ptr update(Ptr t) override {
if (!t) return t;
t->cnt = 1;
t->sum = t->key;
if (t->l) t->cnt += t->l->cnt, t->sum = f(t->l->sum, t->sum);
if (t->r) t->cnt += t->r->cnt, t->sum = f(t->sum, t->r->sum);
return t;
}
protected:
inline T sum(const Ptr t) { return t ? t->sum : T(); }
void push(Ptr t) override {
if (!t) return;
if (t->rev) {
if (t->l) toggle(t->l);
if (t->r) toggle(t->r);
t->rev = false;
}
}
};
/**
* @brief 反転可能平衡二分木(基底クラス)
*/
#line 2 "lct/reversible-bbst-base.hpp"
template <typename Tree, typename Node, typename T, T (*f)(T, T), T (*ts)(T)>
struct ReversibleBBST : Tree {
using Tree::merge;
using Tree::split;
using typename Tree::Ptr;
ReversibleBBST() = default;
virtual void toggle(Ptr t) {
if(!t) return;
swap(t->l, t->r);
t->sum = ts(t->sum);
t->rev ^= true;
}
T fold(Ptr &t, int a, int b) {
auto x = split(t, a);
auto y = split(x.second, b - a);
auto ret = sum(y.first);
t = merge(x.first, merge(y.first, y.second));
return ret;
}
void reverse(Ptr &t, int a, int b) {
auto x = split(t, a);
auto y = split(x.second, b - a);
toggle(y.first);
t = merge(x.first, merge(y.first, y.second));
}
Ptr update(Ptr t) override {
if (!t) return t;
t->cnt = 1;
t->sum = t->key;
if (t->l) t->cnt += t->l->cnt, t->sum = f(t->l->sum, t->sum);
if (t->r) t->cnt += t->r->cnt, t->sum = f(t->sum, t->r->sum);
return t;
}
protected:
inline T sum(const Ptr t) { return t ? t->sum : T(); }
void push(Ptr t) override {
if (!t) return;
if (t->rev) {
if (t->l) toggle(t->l);
if (t->r) toggle(t->r);
t->rev = false;
}
}
};
/**
* @brief 反転可能平衡二分木(基底クラス)
*/
Back to top page