17template<
class P,
class K>
class Node {
19 P* self() {
return static_cast<P*
>(
this); }
20 const P* self()
const {
return static_cast<const P*
>(
this); }
23 constexpr Node() noexcept = default;
27 [[nodiscard]]
bool contains(const K& k) noexcept {
29 for (
auto n =
this; n; n = n->self()->lt(k) ? n->bot : n->top)
30 if (n->self()->eq(k))
return n->splay(),
true;
36 constexpr P*
find(
const K& k)
noexcept {
39 for (
auto n =
this; n;) {
40 if (n->self()->eq(k))
return n->splay(), n->self();
42 if (n->self()->lt(k)) {
66 constexpr void splay() noexcept {
68 if (
auto pp = p->aux_parent()) {
69 if (p->bot ==
this && pp->bot == p) {
72 }
else if (p->top ==
this && pp->top == p) {
75 }
else if (p->bot ==
this && pp->top == p) {
79 assert(p->top ==
this && pp->bot == p);
83 }
else if (p->bot ==
this) {
86 assert(p->top ==
this);
104 template<
size_t l>
constexpr void rotate() noexcept {
105 constexpr size_t r = (l + 1) % 2;
106 constexpr auto child = [](
Node* n,
size_t i) ->
Node*& {
return i == 0 ? n->
bot : n->
top; };
110 auto c = child(x, r);
111 auto b = child(c, l);
113 if (b) b->parent = x;
116 if (child(p, l) == x) {
118 }
else if (child(p, r) == x) {
151 Node* prev =
nullptr;
152 for (
auto curr =
this; curr; prev = curr, curr = curr->
parent) {
154 assert(!prev || prev->
parent == curr);
163 constexpr P*
lca(
Node* other)
noexcept {
return this->
expose(), other->expose(); }
168 if (
this == other)
return true;
172 while (
auto p = curr->aux_parent()) curr = p;
173 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.