17template<
class P,
class K>
20 P* self() {
return static_cast<P*
>(
this); }
21 const P* self()
const {
return static_cast<const P*
>(
this); }
24 constexpr Node() noexcept = default;
28 [[nodiscard]]
bool contains(const K& k) noexcept {
30 for (
auto n =
this; n; n = n->self()->lt(k) ? n->bot : n->top)
31 if (n->self()->eq(k))
return n->splay(),
true;
37 constexpr P*
find(
const K& k)
noexcept {
40 for (
auto n =
this; n;) {
41 if (n->self()->eq(k))
return n->splay(), n->self();
43 if (n->self()->lt(k)) {
67 constexpr void splay() noexcept {
69 if (
auto pp = p->aux_parent()) {
70 if (p->bot ==
this && pp->bot == p) {
73 }
else if (p->top ==
this && pp->top == p) {
76 }
else if (p->bot ==
this && pp->top == p) {
80 assert(p->top ==
this && pp->bot == p);
84 }
else if (p->bot ==
this) {
87 assert(p->top ==
this);
107 constexpr size_t r = (l + 1) % 2;
108 constexpr auto child = [](
Node* n,
size_t i) ->
Node*& {
return i == 0 ? n->
bot : n->
top; };
112 auto c = child(x, r);
113 auto b = child(c, l);
115 if (b) b->parent = x;
118 if (child(p, l) == x) {
120 }
else if (child(p, r) == x) {
153 Node* prev =
nullptr;
154 for (
auto curr =
this; curr; prev = curr, curr = curr->
parent) {
156 assert(!prev || prev->
parent == curr);
165 constexpr P*
lca(
Node* other)
noexcept {
return this->
expose(), other->expose(); }
170 if (
this == other)
return true;
174 while (
auto p = curr->aux_parent())
176 return curr == other;
constexpr P * lca(Node *other) noexcept
Least Common Ancestor of this and other in the aux tree; leaves other exposed.
constexpr Node * aux_parent() noexcept
constexpr void link(Node *child) noexcept
Registers the edge this -> child in the aux tree.
constexpr void ror() noexcept
Node * bot
left/deeper/bottom/leaf-direction
constexpr P * expose() noexcept
Make a preferred path from this to root while putting this at the root of the aux tree.
constexpr bool is_descendant_of(Node *other) noexcept
Is this a descendant of other in the aux tree?
bool contains(const D *&k) noexcept
constexpr void rol() noexcept
constexpr void rotate() noexcept
Helpfer for Splay-Tree: rotate left/right:
constexpr P * path_parent() noexcept
constexpr P * find(const K &k) noexcept
Find k or the element just greater than k.
Node * top
right/shallower/top/root-direction
constexpr Node() noexcept=default
constexpr void splay() noexcept
Splays this to the root of its splay tree.