GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 0.0% 0 / 0 / 84
Functions: 0.0% 0 / 0 / 9
Branches: 0.0% 0 / 52 / 86

lct.hpp
Line Branch Exec Source
1 #pragma once
2
3 #include <cassert>
4 #include <utility>
5
6 namespace lct {
7
8 struct node {
9 node* p;
10 node* c[2];
11
12 int s;
13
14 bool flip;
15
16 // isroot
17 inline bool r() { return p == nullptr || !(this == p->c[0] || this == p->c[1]); }
18 // direction
19 inline bool d() { assert(!r()); return this == p->c[1]; }
20
21 inline void update() { s = 1 + (c[0] ? c[0]->s : 0) + (c[1] ? c[1]->s : 0); }
22 void propogate() {
23 if(flip) {
24 std::swap(c[0], c[1]);
25 if(c[0]) c[0]->flip = !c[0]->flip;
26 if(c[1]) c[1]->flip = !c[1]->flip;
27 flip = false;
28 }
29 }
30
31 // precondition: parent and current are propogated
32 void rot() {
33 assert(!r());
34
35 int x = d();
36 node* pa = p;
37 node* ch = c[!x];
38
39 assert(!pa->flip);
40 assert(!flip);
41
42 assert((!ch) || ch->p == this);
43
44 if(!pa->r()) pa->p->c[pa->d()] = this;
45 this->p = pa->p;
46
47 pa->c[x] = ch;
48 if(ch) ch->p = pa;
49
50 this->c[!x] = pa;
51 pa->p = this;
52
53 pa->update();
54 update();
55 }
56
57 // postcondition: always propogated
58 void splay() {
59 if(r()) {
60 update();
61 propogate();
62 return;
63 }
64
65 while(!r()) {
66 if(!p->r()) {
67 node* gp = p->p;
68 node* pa = p;
69 gp->propogate();
70 pa->propogate();
71 propogate();
72 if(d() == p->d()) {
73 pa->rot();
74 assert(p == pa);
75 } else {
76 rot();
77 assert(p == gp);
78 }
79 rot();
80 } else {
81 p->propogate();
82 propogate();
83 rot();
84 assert(r());
85 }
86 }
87 update();
88 }
89
90 // attach on right side
91 // precondition: propogated
92 void make_child(node* n) {
93 assert(!flip);
94 assert(r());
95
96 if(c[1]) {
97 node* v = c[1];
98 c[1] = nullptr;
99 assert(v->r());
100
101 update();
102 }
103
104 assert(!flip);
105 assert(!c[1]);
106
107 if(n) {
108
109 assert(n->r());
110 assert(n->p == this);
111
112 c[1] = n;
113 assert(c[1]->p == this);
114
115 update();
116 }
117 }
118
119 // postcondition: propogated
120 void expose() {
121 splay();
122 assert(!flip);
123 make_child(nullptr);
124 while(p) {
125 assert(r());
126 p->splay();
127 p->make_child(this);
128 assert(!p->flip);
129 assert(!flip);
130 rot();
131 update();
132 assert(r());
133 }
134 assert(!p);
135 assert(!c[1]);
136 }
137
138 // does not propogate
139 void make_root() {
140 expose();
141 assert(p == nullptr);
142 assert(r());
143 flip = !flip;
144 }
145
146 };
147
148 } // namespace lct
149