平衡樹板子
阿新 • • 發佈:2022-03-24
Treap
code
struct Treap{ struct node{ int l,r,val,key,siz,cnt; }t[maxn]; int tot,root; int New(int x){ t[++tot].val=x; t[tot].key=rand(); t[tot].siz=t[tot].cnt=1; return tot; } void push_up(int x){t[x].siz=t[t[x].l].siz+t[t[x].r].siz+t[x].cnt;} void zig(int &x){ int y=t[x].l; t[x].l=t[y].r; t[y].r=x; x=y; push_up(t[x].r); push_up(x); } void zag(int &x){ int y=t[x].r; t[x].r=t[y].l; t[y].l=x; x=y; push_up(t[x].l); push_up(x); } void insert(int &x,int val){ if(x==0)return x=New(val),void(); if(t[x].val==val)return ++t[x].cnt,++t[x].siz,void(); if(val<t[x].val){ insert(t[x].l,val); push_up(x); if(t[x].key<t[t[x].l].key)return zig(x); } if(val>t[x].val){ insert(t[x].r,val); push_up(x); if(t[x].key<t[t[x].r].key)return zag(x); } } void erase(int &x,int val){ if(x==0)return; if(t[x].val==val){ if(t[x].cnt>1)return --t[x].cnt,--t[x].siz,void(); if(!t[x].l&&!t[x].r)return x=0,void(); if(!t[x].r||t[t[x].l].key>t[t[x].r].key)return zig(x),erase(t[x].r,val),push_up(x); if(!t[x].l||t[t[x].l].key<t[t[x].r].key)return zag(x),erase(t[x].l,val),push_up(x); } if(val<t[x].val)erase(t[x].l,val); else erase(t[x].r,val); push_up(x); } int rank(int x,int val){ if(x==0)return 0; if(t[x].val==val)return t[t[x].l].siz; if(t[x].val<val)return rank(t[x].r,val)+t[t[x].l].siz+t[x].cnt; else return rank(t[x].l,val); } int pre(int val){ int x=root,ans=-2147483645; while(x){ if(t[x].val<val)ans=max(ans,t[x].val),x=t[x].r; else x=t[x].l; } return ans; } int next(int val){ int x=root,ans=2147483647; while(x){ if(t[x].val>val)ans=min(ans,t[x].val),x=t[x].l; else x=t[x].r; } return ans; } int kth(int x,int th){ if(th<=t[t[x].l].siz)return kth(t[x].l,th); if(th<=t[t[x].l].siz+t[x].cnt)return t[x].val; return kth(t[x].r,th-t[t[x].l].siz-t[x].cnt); } }T;
FHQ_Treap
code
struct FHQ_Treap{ struct node{ int l,r,size,val,key; }t[maxn]; int tot,root; int New(int x){t[++tot].val=x;t[tot].key=rand();t[tot].size=1;return tot;} void push_up(int x){t[x].size=t[t[x].l].size+t[t[x].r].size+1;} void split(int x,int &rtx,int &rty,int val){ if(x==0)return rtx=rty=0,void(); if(val<t[x].val){split(t[x].l,rtx,t[x].l,val);rty=x;push_up(rty);return;} else{split(t[x].r,t[x].r,rty,val);rtx=x;push_up(rtx);return;} } int merge(int x,int y){ if(!x||!y)return x|y; if(t[x].key<t[y].key){t[x].r=merge(t[x].r,y);push_up(x);return x;} else{t[y].l=merge(x,t[y].l);push_up(y);return y;} } void insert(int x){ int l=0,r=0;split(root,l,r,x); root=merge(merge(l,New(x)),r); } void erase(int x){ int l,m,r;split(root,l,r,x);split(l,l,m,x-1); m=merge(t[m].l,t[m].r); root=merge(merge(l,m),r); } int kth(int x,int id){ if(t[t[x].l].size+1==id)return t[x].val; if(t[t[x].l].size>=id)return kth(t[x].l,id); return kth(t[x].r,id-t[t[x].l].size-1); } int rank(int x){ int l=0,r=0,ans=0; split(root,l,r,x-1); ans=t[l].size+1; root=merge(l,r); return ans; } int pre(int x){ int l=0,r=0,ans=0; split(root,l,r,x-1); ans=kth(l,t[l].size); root=merge(l,r); return ans; } int nxt(int x){ int l=0,r=0,ans=0; split(root,l,r,x); ans=kth(r,1); root=merge(l,r); return ans; } }T;