On this page
article
Treap Implicita
Sobre
Todas as operacoes custam
O(log(n)) com alta probabilidade
Link original: treapImplicita.cpp
Código
mt19937 rng((int) chrono::steady_clock::now().time_since_epoch().count());
template<typename T> struct treap {
struct node {
node *l, *r;
int p, sz;
T val, sub, lazy;
bool rev;
node(T v) : l(NULL), r(NULL), p(rng()), sz(1), val(v), sub(v), lazy(0), rev(0) {}
void prop() {
if (lazy) {
val += lazy, sub += lazy*sz;
if (l) l->lazy += lazy;
if (r) r->lazy += lazy;
}
if (rev) {
swap(l, r);
if (l) l->rev ^= 1;
if (r) r->rev ^= 1;
}
lazy = 0, rev = 0;
}
void update() {
sz = 1, sub = val;
if (l) l->prop(), sz += l->sz, sub += l->sub;
if (r) r->prop(), sz += r->sz, sub += r->sub;
}
};
node* root;
treap() { root = NULL; }
treap(const treap& t) {
throw logic_error("Nao copiar a treap!");
}
~treap() {
vector<node*> q = {root};
while (q.size()) {
node* x = q.back(); q.pop_back();
if (!x) continue;
q.push_back(x->l), q.push_back(x->r);
delete x;
}
}
int size(node* x) { return x ? x->sz : 0; }
int size() { return size(root); }
void join(node* l, node* r, node*& i) { // assume que l < r
if (!l or !r) return void(i = l ? l : r);
l->prop(), r->prop();
if (l->p > r->p) join(l->r, r, l->r), i = l;
else join(l, r->l, r->l), i = r;
i->update();
}
void split(node* i, node*& l, node*& r, int v, int key = 0) {
if (!i) return void(r = l = NULL);
i->prop();
if (key + size(i->l) < v) split(i->r, i->r, r, v, key+size(i->l)+1), l = i;
else split(i->l, l, i->l, v, key), r = i;
i->update();
}
void push_back(T v) {
node* i = new node(v);
join(root, i, root);
}
T query(int l, int r) {
node *L, *M, *R;
split(root, M, R, r+1), split(M, L, M, l);
T ans = M->sub;
join(L, M, M), join(M, R, root);
return ans;
}
void update(int l, int r, T s) {
node *L, *M, *R;
split(root, M, R, r+1), split(M, L, M, l);
M->lazy += s;
join(L, M, M), join(M, R, root);
}
void reverse(int l, int r) {
node *L, *M, *R;
split(root, M, R, r+1), split(M, L, M, l);
M->rev ^= 1;
join(L, M, M), join(M, R, root);
}
};