src/jiangly/ds/08D-Mysterious-Balanced-Tree.hpp
Code
struct Node {
Node *l = nullptr;
Node *r = nullptr;
int cnt = 0;
int cntnew = 0;
};
Node *add(int l, int r, int x, int isnew) {
Node *t = new Node;
t->cnt = 1;
t->cntnew = isnew;
if (r - l == 1) {
return t;
}
int m = (l + r) / 2;
if (x < m) {
t->l = add(l, m, x, isnew);
} else {
t->r = add(m, r, x, isnew);
}
return t;
}
struct Info {
Node *t = nullptr;
int psum = 0;
bool rev = false;
};
void pull(Node *t) {
t->cnt = (t->l ? t->l->cnt : 0) + (t->r ? t->r->cnt : 0);
t->cntnew = (t->l ? t->l->cntnew : 0) + (t->r ? t->r->cntnew : 0);
}
std::pair<Node *, Node *> split(Node *t, int l, int r, int x, bool rev) {
if (!t) {
return {t, t};
}
if (x == 0) {
return {nullptr, t};
}
if (x == t->cnt) {
return {t, nullptr};
}
if (r - l == 1) {
Node *t2 = new Node;
t2->cnt = t->cnt - x;
t->cnt = x;
return {t, t2};
}
Node *t2 = new Node;
int m = (l + r) / 2;
if (!rev) {
if (t->l && x <= t->l->cnt) {
std::tie(t->l, t2->l) = split(t->l, l, m, x, rev);
t2->r = t->r;
t->r = nullptr;
} else {
std::tie(t->r, t2->r) = split(t->r, m, r, x - (t->l ? t->l->cnt : 0), rev);
}
} else {
if (t->r && x <= t->r->cnt) {
std::tie(t->r, t2->r) = split(t->r, m, r, x, rev);
t2->l = t->l;
t->l = nullptr;
} else {
std::tie(t->l, t2->l) = split(t->l, l, m, x - (t->r ? t->r->cnt : 0), rev);
}
}
pull(t);
pull(t2);
return {t, t2};
}
Node *merge(Node *t1, Node *t2, int l, int r) {
if (!t1) {
return t2;
}
if (!t2) {
return t1;
}
if (r - l == 1) {
t1->cnt += t2->cnt;
t1->cntnew += t2->cntnew;
delete t2;
return t1;
}
int m = (l + r) / 2;
t1->l = merge(t1->l, t2->l, l, m);
t1->r = merge(t1->r, t2->r, m, r);
delete t2;
pull(t1);
return t1;
}
#line 1 "src/jiangly/ds/08D-Mysterious-Balanced-Tree.hpp"
struct Node {
Node *l = nullptr;
Node *r = nullptr;
int cnt = 0;
int cntnew = 0;
};
Node *add(int l, int r, int x, int isnew) {
Node *t = new Node;
t->cnt = 1;
t->cntnew = isnew;
if (r - l == 1) {
return t;
}
int m = (l + r) / 2;
if (x < m) {
t->l = add(l, m, x, isnew);
} else {
t->r = add(m, r, x, isnew);
}
return t;
}
struct Info {
Node *t = nullptr;
int psum = 0;
bool rev = false;
};
void pull(Node *t) {
t->cnt = (t->l ? t->l->cnt : 0) + (t->r ? t->r->cnt : 0);
t->cntnew = (t->l ? t->l->cntnew : 0) + (t->r ? t->r->cntnew : 0);
}
std::pair<Node *, Node *> split(Node *t, int l, int r, int x, bool rev) {
if (!t) {
return {t, t};
}
if (x == 0) {
return {nullptr, t};
}
if (x == t->cnt) {
return {t, nullptr};
}
if (r - l == 1) {
Node *t2 = new Node;
t2->cnt = t->cnt - x;
t->cnt = x;
return {t, t2};
}
Node *t2 = new Node;
int m = (l + r) / 2;
if (!rev) {
if (t->l && x <= t->l->cnt) {
std::tie(t->l, t2->l) = split(t->l, l, m, x, rev);
t2->r = t->r;
t->r = nullptr;
} else {
std::tie(t->r, t2->r) = split(t->r, m, r, x - (t->l ? t->l->cnt : 0), rev);
}
} else {
if (t->r && x <= t->r->cnt) {
std::tie(t->r, t2->r) = split(t->r, m, r, x, rev);
t2->l = t->l;
t->l = nullptr;
} else {
std::tie(t->l, t2->l) = split(t->l, l, m, x - (t->r ? t->r->cnt : 0), rev);
}
}
pull(t);
pull(t2);
return {t, t2};
}
Node *merge(Node *t1, Node *t2, int l, int r) {
if (!t1) {
return t2;
}
if (!t2) {
return t1;
}
if (r - l == 1) {
t1->cnt += t2->cnt;
t1->cntnew += t2->cntnew;
delete t2;
return t1;
}
int m = (l + r) / 2;
t1->l = merge(t1->l, t2->l, l, m);
t1->r = merge(t1->r, t2->r, m, r);
delete t2;
pull(t1);
return t1;
}
Back to top page