src/jiangly/ds/07A-Splay.hpp
Code
struct Node {
Node *l = nullptr;
Node *r = nullptr;
int cnt = 0;
i64 sum = 0;
};
Node *add(Node *t, int l, int r, int p, int v) {
Node *x = new Node;
if (t) {
*x = *t;
}
x->cnt += 1;
x->sum += v;
if (r - l == 1) {
return x;
}
int m = (l + r) / 2;
if (p < m) {
x->l = add(x->l, l, m, p, v);
} else {
x->r = add(x->r, m, r, p, v);
}
return x;
}
int find(Node *tl, Node *tr, int l, int r, int x) {
if (r <= x) {
return -1;
}
if (l >= x) {
int cnt = (tr ? tr->cnt : 0) - (tl ? tl->cnt : 0);
if (cnt == 0) {
return -1;
}
if (r - l == 1) {
return l;
}
}
int m = (l + r) / 2;
int res = find(tl ? tl->l : tl, tr ? tr->l : tr, l, m, x);
if (res == -1) {
res = find(tl ? tl->r : tl, tr ? tr->r : tr, m, r, x);
}
return res;
}
std::pair<int, i64> get(Node *t, int l, int r, int x, int y) {
if (l >= y || r <= x || !t) {
return {0, 0LL};
}
if (l >= x && r <= y) {
return {t->cnt, t->sum};
}
int m = (l + r) / 2;
auto [cl, sl] = get(t->l, l, m, x, y);
auto [cr, sr] = get(t->r, m, r, x, y);
return {cl + cr, sl + sr};
}
struct Tree {
int add = 0;
int val = 0;
int id = 0;
Tree *ch[2] = {};
Tree *p = nullptr;
};
int pos(Tree *t) {
return t->p->ch[1] == t;
}
void add(Tree *t, int v) {
t->val += v;
t->add += v;
}
void push(Tree *t) {
if (t->ch[0]) {
add(t->ch[0], t->add);
}
if (t->ch[1]) {
add(t->ch[1], t->add);
}
t->add = 0;
}
void rotate(Tree *t) {
Tree *q = t->p;
int x = !pos(t);
q->ch[!x] = t->ch[x];
if (t->ch[x]) t->ch[x]->p = q;
t->p = q->p;
if (q->p) q->p->ch[pos(q)] = t;
t->ch[x] = q;
q->p = t;
}
void splay(Tree *t) {
std::vector<Tree *> s;
for (Tree *i = t; i->p; i = i->p) s.push_back(i->p);
while (!s.empty()) {
push(s.back());
s.pop_back();
}
push(t);
while (t->p) {
if (t->p->p) {
if (pos(t) == pos(t->p)) rotate(t->p);
else rotate(t);
}
rotate(t);
}
}
void insert(Tree *&t, Tree *x, Tree *p = nullptr) {
if (!t) {
t = x;
x->p = p;
return;
}
push(t);
if (x->val < t->val) {
insert(t->ch[0], x, t);
} else {
insert(t->ch[1], x, t);
}
}
void dfs(Tree *t) {
if (!t) {
return;
}
push(t);
dfs(t->ch[0]);
std::cerr << t->val << " ";
dfs(t->ch[1]);
}
std::pair<Tree *, Tree *> split(Tree *t, int x) {
if (!t) {
return {t, t};
}
Tree *v = nullptr;
Tree *j = t;
for (Tree *i = t; i; ) {
push(i);
j = i;
if (i->val >= x) {
v = i;
i = i->ch[0];
} else {
i = i->ch[1];
}
}
splay(j);
if (!v) {
return {j, nullptr};
}
splay(v);
Tree *u = v->ch[0];
if (u) {
v->ch[0] = u->p = nullptr;
}
// std::cerr << "split " << x << "\n";
// dfs(u);
// std::cerr << "\n";
// dfs(v);
// std::cerr << "\n";
return {u, v};
}
Tree *merge(Tree *l, Tree *r) {
if (!l) {
return r;
}
if (!r) {
return l;
}
Tree *i = l;
while (i->ch[1]) {
i = i->ch[1];
}
splay(i);
i->ch[1] = r;
r->p = i;
return i;
}
#line 1 "src/jiangly/ds/07A-Splay.hpp"
struct Node {
Node *l = nullptr;
Node *r = nullptr;
int cnt = 0;
i64 sum = 0;
};
Node *add(Node *t, int l, int r, int p, int v) {
Node *x = new Node;
if (t) {
*x = *t;
}
x->cnt += 1;
x->sum += v;
if (r - l == 1) {
return x;
}
int m = (l + r) / 2;
if (p < m) {
x->l = add(x->l, l, m, p, v);
} else {
x->r = add(x->r, m, r, p, v);
}
return x;
}
int find(Node *tl, Node *tr, int l, int r, int x) {
if (r <= x) {
return -1;
}
if (l >= x) {
int cnt = (tr ? tr->cnt : 0) - (tl ? tl->cnt : 0);
if (cnt == 0) {
return -1;
}
if (r - l == 1) {
return l;
}
}
int m = (l + r) / 2;
int res = find(tl ? tl->l : tl, tr ? tr->l : tr, l, m, x);
if (res == -1) {
res = find(tl ? tl->r : tl, tr ? tr->r : tr, m, r, x);
}
return res;
}
std::pair<int, i64> get(Node *t, int l, int r, int x, int y) {
if (l >= y || r <= x || !t) {
return {0, 0LL};
}
if (l >= x && r <= y) {
return {t->cnt, t->sum};
}
int m = (l + r) / 2;
auto [cl, sl] = get(t->l, l, m, x, y);
auto [cr, sr] = get(t->r, m, r, x, y);
return {cl + cr, sl + sr};
}
struct Tree {
int add = 0;
int val = 0;
int id = 0;
Tree *ch[2] = {};
Tree *p = nullptr;
};
int pos(Tree *t) {
return t->p->ch[1] == t;
}
void add(Tree *t, int v) {
t->val += v;
t->add += v;
}
void push(Tree *t) {
if (t->ch[0]) {
add(t->ch[0], t->add);
}
if (t->ch[1]) {
add(t->ch[1], t->add);
}
t->add = 0;
}
void rotate(Tree *t) {
Tree *q = t->p;
int x = !pos(t);
q->ch[!x] = t->ch[x];
if (t->ch[x]) t->ch[x]->p = q;
t->p = q->p;
if (q->p) q->p->ch[pos(q)] = t;
t->ch[x] = q;
q->p = t;
}
void splay(Tree *t) {
std::vector<Tree *> s;
for (Tree *i = t; i->p; i = i->p) s.push_back(i->p);
while (!s.empty()) {
push(s.back());
s.pop_back();
}
push(t);
while (t->p) {
if (t->p->p) {
if (pos(t) == pos(t->p)) rotate(t->p);
else rotate(t);
}
rotate(t);
}
}
void insert(Tree *&t, Tree *x, Tree *p = nullptr) {
if (!t) {
t = x;
x->p = p;
return;
}
push(t);
if (x->val < t->val) {
insert(t->ch[0], x, t);
} else {
insert(t->ch[1], x, t);
}
}
void dfs(Tree *t) {
if (!t) {
return;
}
push(t);
dfs(t->ch[0]);
std::cerr << t->val << " ";
dfs(t->ch[1]);
}
std::pair<Tree *, Tree *> split(Tree *t, int x) {
if (!t) {
return {t, t};
}
Tree *v = nullptr;
Tree *j = t;
for (Tree *i = t; i; ) {
push(i);
j = i;
if (i->val >= x) {
v = i;
i = i->ch[0];
} else {
i = i->ch[1];
}
}
splay(j);
if (!v) {
return {j, nullptr};
}
splay(v);
Tree *u = v->ch[0];
if (u) {
v->ch[0] = u->p = nullptr;
}
// std::cerr << "split " << x << "\n";
// dfs(u);
// std::cerr << "\n";
// dfs(v);
// std::cerr << "\n";
return {u, v};
}
Tree *merge(Tree *l, Tree *r) {
if (!l) {
return r;
}
if (!r) {
return l;
}
Tree *i = l;
while (i->ch[1]) {
i = i->ch[1];
}
splay(i);
i->ch[1] = r;
r->p = i;
return i;
}
Back to top page