非旋treap指针板子
普通平衡树:
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+5; struct FHQ_Treap{ protected: struct node{ node *ch[2]; int siz,val,key; node(int siz=1,int val=0,int key=rand()):siz(siz),val(val),key(key){ ch[0]=ch[1]=NULL; } void upd(){siz=(ch[0]?ch[0]->siz:0)+(ch[1]?ch[1]->siz:0)+1;} int rk(){return ch[0]?ch[0]->siz+1:1;} }poor[maxn],*tail,*root; void split(node *o,node *&a,node *&b,int val){ if(!o){ a=b=NULL; return; } if(o->val<=val){ a=o; split(o->ch[1],a->ch[1],b,val); a->upd(); }else{ b=o; split(o->ch[0],a,b->ch[0],val); b->upd(); } } void merge(node *&o,node *a,node *b){ if(!a||!b){ o=a?a:b; return; } if(a->key<=b->key){ o=a; merge(o->ch[1],a->ch[1],b); }else{ o=b; merge(o->ch[0],a,b->ch[0]); } o->upd(); } node *kth(node *o,int k){ while(o->rk()!=k){ if(o->rk()<k)k-=o->rk(),o=o->ch[1]; else o=o->ch[0]; } return o; } public: FHQ_Treap(){root=NULL;tail=poor;} void ins(int val){ node *x=NULL,*y=NULL; node *z=new(tail++)node(1,val); split(root,x,y,val); merge(x,x,z); merge(root,x,y); } void del(int val){ node *x=NULL,*y=NULL,*z=NULL; split(root,x,y,val); split(x,x,z,val-1); merge(z,z->ch[0],z->ch[1]); merge(x,x,z); merge(root,x,y); } int rnk(int val){ node *x=NULL,*y=NULL; split(root,x,y,val-1); int res=(x?x->siz:0)+1; merge(root,x,y); return res; } int kth(int rank){ return kth(root,rank)->val; } int pre(int val) { node *x =NULL,*y=NULL; split(root,x,y,val-1); node *z=kth(x,x->siz); merge(root,x,y); return z->val; } int nxt(int val) { node *x=NULL,*y=NULL; split(root,x,y,val); node *z=kth(y,1); merge(root,x,y); return z->val; } }fhq; int n,opt,x; int main(){ scanf("%d",&n); while(n--){ scanf("%d%d",&opt,&x); if(opt==1)fhq.ins(x); if(opt==2)fhq.del(x); if(opt==3)printf("%d\n",fhq.rnk(x)); if(opt==4)printf("%d\n",fhq.kth(x)); if(opt==5)printf("%d\n",fhq.pre(x)); if(opt==6)printf("%d\n",fhq.nxt(x)); } return 0; }
文艺平衡树:
#include<bits/stdc++.h> using namespace std; struct node;typedef node* ptr; const int maxn=1e5+5; struct node{ ptr ls,rs; int mark,size; int val,dat; node(); ptr init(int v){ val=v;size=1; mark=0;dat=rand(); return this; } ptr pushd(){ swap(ls,rs); mark^=1; return this; } ptr pushdown(){ if(mark){ ls->pushd(); rs->pushd(); mark=0; } return this; } ptr pushup(){ size=ls->size+rs->size+1; return this; } }e[maxn],*tail=e,*root=e; node::node(){ls=rs=e;} ptr newnode(int v){return (++tail)->init(v);} void split(ptr p,ptr &x,ptr &y,int siz){ if(p==e){ x=y=e; return; } if(p->pushdown()->ls->size<siz){ x=p; split(p->rs,p->rs,y,siz-p->ls->size-1); }else{ y=p; split(p->ls,x,p->ls,siz); } p->pushup(); } ptr merge(ptr x,ptr y){ if(x==e)return y; if(y==e)return x; if(x->pushdown()->dat<y->pushdown()->dat){ return x->rs=merge(x->rs,y),x->pushup(); }else{ return y->ls=merge(x,y->ls),y->pushup(); } } void mark(int l,int r){ ptr x,y,p,q; split(root,x,y,r); split(x,p,q,l-1); root=merge(merge(p,q->pushd()),y); } void print(ptr p){ p->pushdown(); if(p->ls!=e)print(p->ls); printf("%d ",p->val); if(p->rs!=e)print(p->rs); } int n,m,l,r; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) root=merge(root,newnode(i)); while(m--){ scanf("%d%d",&l,&r); mark(l,r); } print(root); return 0; }