splay模板 指標版
阿新 • • 發佈:2020-09-16
普通平衡樹板子
參考了大佬部落格
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> pii; #define forg(i,x) for(int i=first[x];i;i=nxt[i]) #define uu unsigned #define fi first #define se second #define od(x) ((x)&1) #define ev(x) (od(x)^1) #define mi2(x) (1<<(x)) #define scanf a1234=scanf #define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout) int a1234; char buf[1<<18],*bufs=buf,*buft=buf; inline int gc(){ return bufs==buft&&(buft=(bufs=buf)+fread(buf,1,1<<18,stdin)),bufs==buft?-1:*bufs++; } inline void xxx(){for(;;);} const int mxn=1e5+9; int n; #define lch ch[0] #define rch ch[1] #define inf (0x3f3f3f3f) struct node{ node*ch[2],*prt; int siz,cnt,val; inline void up(){siz=cnt+lch->siz+rch->siz;} }*nil,SS[mxn],*stk[mxn]; class spl{ public: node*rt;int top; inline void init(){ for(int i=0;i<mxn;++i)stk[i]=SS+i; top=mxn-1; nil=stk[top--]; nil->lch=nil->rch=nil->prt=nil,nil->cnt=nil->siz=0; rt=newd(inf,nil),rt->lch=newd(-inf,rt),rt->siz=2; } inline node*newd(int v,node*f){ node*p=stk[top--]; p->lch=p->rch=nil,p->prt=f; p->cnt=p->siz=1,p->val=v; return p; } inline void connect(node*x,node*f,int k){ x->prt=f,f->ch[k]=x; } inline int son(node*x){return x==x->prt->rch;} inline void rotate(node*x){ node*f=x->prt,*g=f->prt; int k=son(x),kk=son(f); connect(x->ch[k^1],f,k),connect(f,x,k^1); f->up(),x->up(); if(g==nil)rt=x,rt->prt=nil;else connect(x,g,kk); } inline void splay(node*x,node*y=nil){ while(x->prt!=y){ node*f=x->prt,*g=f->prt; if(g==y)return rotate(x); if(son(x)^son(f))rotate(x),rotate(x); else rotate(f),rotate(x); } } inline void insert(int x){ node*p=rt; while(1){ ++p->siz; if(p->val==x)return ++p->cnt,splay(p); node*&nxt=p->ch[p->val<x]; if(nxt==nil)return nxt=newd(x,p),splay(nxt); p=nxt; } } inline void erase(int x){ find(x); --rt->cnt,--rt->siz; if(rt->cnt)return; node*p=rt->lch; while(p->rch!=nil)p=p->rch; splay(p,rt); p=rt->lch; p->rch=rt->rch,rt->rch->prt=p,p->up(); stk[++top]=rt; rt=p,rt->prt=nil; } inline node*find(int x){ node*p=rt; while(1){ if(p->val==x)return splay(p),p; p=p->ch[p->val<x]; } } inline node*find1(int x){ node*p=rt,*pres=nil; int res=-inf-2; while(p!=nil){ if(p->val==x)return splay(p),p; if(p->val<x&&p->val>res)res=p->val,pres=p; p=p->ch[p->val<x]; } return splay(pres),pres; } inline int getrk(int x){ find1(x); return rt->val==x?rt->lch->siz:rt->cnt+rt->lch->siz; } inline node*kth(int x){ ++x; node*p=rt; int cnt=0; while(1){ int num=p->lch->siz; if(num<x&&num+p->cnt>=x)return splay(p),p; if(x<=num)p=p->lch; else x-=num+p->cnt,p=p->rch; } } inline node*lower(int x){ return kth(getrk(x)-1); } inline node*upper(int x){ return kth(getrk(x+1)); } }sp; #undef lch #undef rch #undef inf int main(){ sp.init(); scanf("%d",&n);while(n--){ int o,x;scanf("%d%d",&o,&x); switch(o){ case 1:sp.insert(x);break; case 2:sp.erase(x);break; case 3:printf("%d\n",sp.getrk(x));break; case 4:printf("%d\n",sp.kth(x)->val);break; case 5:printf("%d\n",sp.lower(x)->val);break; case 6:printf("%d\n",sp.upper(x)->val);break; } } return 0; }