1. 程式人生 > >【模板】帶旋Treap(指標實現)

【模板】帶旋Treap(指標實現)

解析:

聯賽結束後統一更模板題題解。 陣列實現看這裡

程式碼:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const

inline
int getint(){
	re int num;
	re char c;
	while(!isdigit(c=gc()));num=c^48;
	while(isdigit(c=gc()))num=(num<<
1)+(num<<3)+(c^48); return num; } inline void outint(int a){ static char ch[13]; if(a==0)pc('0'); if(a<0)pc('-'),a=-a; while(a)ch[++ch[0]]=a-a/10*10,a/=10; while(ch[0])pc(ch[ch[0]--]^48); } cs int INF=0x3f3f3f3f; typedef struct treap_node *point; struct treap_node{ point lc,rc; int val,pri,siz,
cnt; treap_node(){ lc=rc=NULL; val=pri=siz=cnt=0; } void init(int _val){ lc=rc=NULL; val=_val; pri=rand(); siz=cnt=1; } void update(){ siz=(lc==NULL?0:lc->siz)+(rc==NULL?0:rc->siz)+cnt; } }; struct TREAP{ point root; void Zig(point &k){ point y=k->lc; k->lc=
y->rc; y->rc=k; y->siz=k->siz; k->update(); k=y; } void Zag(point &k){ point y=k->rc; k->rc=y->lc; y->lc=k; y->siz=k->siz; k->update(); k=y; } void insert(point &k,cs int &key){ if(k==NULL){ k=(point)malloc(sizeof(treap_node)); k->init(key); return ; } ++k->siz; if(k->val==key)return (void)(++k->cnt); if(key>k->val){ insert(k->rc,key); if(k->rc->pri>k->pri)Zag(k); } else { insert(k->lc,key); if(k->lc->pri>k->pri)Zig(k); } } void Insert(cs int &key){insert(root,key);} void del(point &k,cs int &key){ if(k==NULL)return ; if(k->val==key){ if(k->cnt>1)--k->cnt,--k->siz; else if(!k->lc)/*free(k),*/k=k->rc;//不節約空間可以這樣寫, else if(!k->rc)/*free(k),*/k=k->lc;//如果要節約空間請先用tmp保留要指向的兒子,再用free函式 else if(k->lc->pri>k->rc->pri)Zig(k),del(k,key); else Zag(k),del(k,key); return ; } --k->siz; if(key>k->val)del(k->rc,key); else del(k->lc,key); } void Delete(cs int &key){del(root,key);} int queryrank(cs int &key){ point k=root; int ans=0; while(k){ if(k->val==key)return ans+(k->lc?k->lc->siz:0); if(k->val>key)k=k->lc; else ans+=(k->lc?k->lc->siz:0)+k->cnt,k=k->rc; } return ans; } int querykth(int Rank){ point k=root; while(k){ int res=k->lc?k->lc->siz:0; if(res<Rank&&res+k->cnt>=Rank)return k->val; if(res>=Rank)k=k->lc; else Rank-=res+k->cnt,k=k->rc; } return 0; } int querypre(cs int &key){ point k=root; int ans=-INF; while(k){ if(k->val>=key)k=k->lc; else ans=k->val,k=k->rc; } return ans==-INF?-1:ans; } int querysuf(cs int &key){ point k=root; int ans=INF; while(k){ if(k->val<=key)k=k->rc; else ans=k->val,k=k->lc; } return ans==INF?-1:ans; } }Treap; int n; signed main(){ n=getint(); while(n--){ int op=getint(),x=getint(); int ans; switch(op){ case 0:Treap.Insert(x);break; case 1:Treap.Delete(x);break; case 2:outint(Treap.querykth(x)),pc('\n');break; case 3:outint(Treap.queryrank(x)),pc('\n');break; case 4:outint(Treap.querypre(x)),pc('\n');break; case 5:outint(Treap.querysuf(x)),pc('\n');break; } } return 0; }