void unite (pnode &t,pnode l, pnode r) { if (!l || !r) return void(t = l ? l : r); if (l->prior < r->prior) swap (l, r); pnode lt, rt; split (r,lt, rt,l->val); unite (l->l,l->l, lt); unite (l->r,l->r, rt); t=l;upd_sz(t); }
void merge(pnode &t,pnode l,pnode r) //l->leftarray,r->rightarray,t->resulting array { lazy(l); lazy(r); if(!l || !r) t = l?l:r; else if(l->prior>r->prior)merge(l->r,l->r,r),t=l; else merge(r->l,l,r->l),t=r; upd_sz(t); operation(t); }
void split(pnode t,pnode &l,pnode &r,int pos,int add=0) { if(!t)return void(l=r=NULL); lazy(t); int curr_pos = add + sz(t->l); if(curr_pos<=pos)//element at pos goes to left subtree(l) split(t->r,t->r,r,pos,curr_pos+1),l=t; else split(t->l,l,t->l,pos,add),r=t; upd_sz(t); operation(t); }
void erase(pnode &t,int key){ if(!t)return; else if(t->val==key){pnode temp=t;merge(t,t->l,t->r);free(temp);} else erase(t->val<key?t->r:t->l,key); upd_sz(t); }
void insert(pnode &t,pnode it){ if(!t) t=it; else if(it->prior>t->prior)split(t,it->l,it->r,it->val),t=it; else insert(t->val<=it->val?t->r:t->l,it); upd_sz(t); }