This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub kmyk/competitive-programming-library
template <typename T>
struct prbst { // persistent randomized binary search tree
typedef T value_type;
value_type v;
shared_ptr<prbst> l, r;
size_t m_size;
static size_t size(shared_ptr<prbst> const & t) {
return t ? t->m_size : 0;
}
static shared_ptr<prbst> merge(shared_ptr<prbst> const & a, shared_ptr<prbst> const & b) {
if (not a) return b;
if (not b) return a;
if (compare(size(a), size(b))) {
return make_shared<prbst>(b->v, merge(a, b->l), b->r);
} else {
return make_shared<prbst>(a->v, a->l, merge(a->r, b));
}
}
static pair<shared_ptr<prbst>, shared_ptr<prbst> > split(shared_ptr<prbst> const & t, size_t i) { // [0, i) [i, n)
if (not t) return { shared_ptr<prbst>(), shared_ptr<prbst>() };
if (i <= size(t->l)) {
shared_ptr<prbst> l, r; tie(l, r) = split(t->l, i);
return { l, make_shared<prbst>(t->v, r, t->r) };
} else {
shared_ptr<prbst> l, r; tie(l, r) = split(t->r, i - size(t->l) - 1);
return { make_shared<prbst>(t->v, t->l, l), r };
}
}
static shared_ptr<prbst> insert(shared_ptr<prbst> const & t, size_t i, value_type v) {
shared_ptr<prbst> l, r; tie(l, r) = split(t, i);
shared_ptr<prbst> u = make_shared<prbst>(v);
return merge(merge(l, u), r);
}
static pair<shared_ptr<prbst>, value_type> erase(shared_ptr<prbst> const & t, size_t i) { // (t \ t_i, t_i)
shared_ptr<prbst> l, u, r;
tie(l, r) = split(t, i+1);
tie(l, u) = split(l, i);
return { merge(l, r), u->v };
}
// private:
prbst(value_type v) : v(v), l(), r(), m_size(1) {}
prbst(value_type v, shared_ptr<prbst> const & l, shared_ptr<prbst> const & r) : v(v), l(l), r(r), m_size(1 + size(l) + size(r)) {}
static bool compare(size_t a, size_t b) {
static random_device device;
static default_random_engine engine(device());
bernoulli_distribution dist(b /(double) (a + b));
return dist(engine);
}
};
#line 1 "old/persistent-randomized-binary-search-tree.inc.cpp"
template <typename T>
struct prbst { // persistent randomized binary search tree
typedef T value_type;
value_type v;
shared_ptr<prbst> l, r;
size_t m_size;
static size_t size(shared_ptr<prbst> const & t) {
return t ? t->m_size : 0;
}
static shared_ptr<prbst> merge(shared_ptr<prbst> const & a, shared_ptr<prbst> const & b) {
if (not a) return b;
if (not b) return a;
if (compare(size(a), size(b))) {
return make_shared<prbst>(b->v, merge(a, b->l), b->r);
} else {
return make_shared<prbst>(a->v, a->l, merge(a->r, b));
}
}
static pair<shared_ptr<prbst>, shared_ptr<prbst> > split(shared_ptr<prbst> const & t, size_t i) { // [0, i) [i, n)
if (not t) return { shared_ptr<prbst>(), shared_ptr<prbst>() };
if (i <= size(t->l)) {
shared_ptr<prbst> l, r; tie(l, r) = split(t->l, i);
return { l, make_shared<prbst>(t->v, r, t->r) };
} else {
shared_ptr<prbst> l, r; tie(l, r) = split(t->r, i - size(t->l) - 1);
return { make_shared<prbst>(t->v, t->l, l), r };
}
}
static shared_ptr<prbst> insert(shared_ptr<prbst> const & t, size_t i, value_type v) {
shared_ptr<prbst> l, r; tie(l, r) = split(t, i);
shared_ptr<prbst> u = make_shared<prbst>(v);
return merge(merge(l, u), r);
}
static pair<shared_ptr<prbst>, value_type> erase(shared_ptr<prbst> const & t, size_t i) { // (t \ t_i, t_i)
shared_ptr<prbst> l, u, r;
tie(l, r) = split(t, i+1);
tie(l, u) = split(l, i);
return { merge(l, r), u->v };
}
// private:
prbst(value_type v) : v(v), l(), r(), m_size(1) {}
prbst(value_type v, shared_ptr<prbst> const & l, shared_ptr<prbst> const & r) : v(v), l(l), r(r), m_size(1 + size(l) + size(r)) {}
static bool compare(size_t a, size_t b) {
static random_device device;
static default_random_engine engine(device());
bernoulli_distribution dist(b /(double) (a + b));
return dist(engine);
}
};