平衡树学习笔记
1.平衡树是一棵二叉查找树。
二叉排序树是一棵空树,或是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
2.平衡二叉树(Balanced Binary Tree)具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。
例题:bzoj3224/tyvj 1728/luogu 3369 普通平衡树
1.带旋treap
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define nl NULL 5 using namespace std; 6 inline int in(){ 7 int x=0;bool f=0; char c; 8 for (;(c=getchar())<'0'||c>'9';f=c=='-'); 9 for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0'); 10 return f?-x:x; 11 } 12 int n,opt,x; 13 inline int rd(){ 14 static int x=23333; 15 x^=x<<13;x^=x>>17;x^=x<<5;return x; 16 } 17 struct treap{ 18 treap *ls,*rs; 19 int val,pri,num,siz; 20 treap(int val):val(val),pri(rd()),num(1),siz(1),ls(nl),rs(nl){} 21 inline void combine(){siz=(ls?ls->siz:0)+(rs?rs->siz:0)+num;} 22 }*rt; 23 inline void lturn(treap* &x){ 24 treap *y=x->rs;x->rs=y->ls;y->ls=x;y->siz=x->siz;x->combine();x=y; 25 } 26 inline void rturn(treap* &x){ 27 treap *y=x->ls;x->ls=y->rs;y->rs=x;y->siz=x->siz;x->combine();x=y; 28 } 29 inline void ins(treap* &x,int val){ 30 if (x==nl){x=new treap(val);return;} 31 if (val==x->val) x->num++; 32 else if (val>x->val) {ins(x->rs,val);if (x->rs->pri<x->pri) lturn(x);} 33 else {ins(x->ls,val);if(x->ls->pri<x->pri) rturn(x);}x->combine(); 34 } 35 inline void del(treap* &x,int val){ 36 if (x==nl) return; 37 if (val==x->val){ 38 if (x->num>1) x->num--,x->siz--; 39 else if (x->ls==nl||x->rs==nl){ 40 treap *t=x; 41 x=(x->ls==nl)?x->rs:x->ls;delete t; 42 }else if (x->ls->pri<x->rs->pri) rturn(x),del(x,val); 43 else lturn(x),del(x,val); 44 }else if (val<x->val) x->siz--,del(x->ls,val); 45 else x->siz--,del(x->rs,val); 46 } 47 inline int qrank(treap* &x,int val){ 48 if (x==nl) return 0; 49 if (x->ls==nl){ 50 if (val==x->val) return 1; 51 if (val<x->val) return 0; 52 return qrank(x->rs,val)+x->num; 53 }if (val==x->val) return x->ls->siz+1; 54 if (val<x->val) return qrank(x->ls,val); 55 return qrank(x->rs,val)+x->ls->siz+x->num; 56 } 57 inline int qnum(treap *x,int val){ 58 if (x==nl) return 0; 59 if (x->ls==nl){ 60 if (val<=x->num) return x->val; 61 return qnum(x->rs,val-x->num); 62 }if (val<=x->ls->siz) return qnum(x->ls,val); 63 if (val>x->ls->siz+x->num) return qnum(x->rs,val-x->ls->siz-x->num); 64 return x->val; 65 } 66 inline int qpre(treap *x,int val,int ans){ 67 if (x==nl) return ans; 68 if (val>x->val) return qpre(x->rs,val,x->val); 69 return qpre(x->ls,val,ans); 70 } 71 inline int qpost(treap *x,int val,int ans){ 72 if (x==nl) return ans; 73 if (val<x->val) return qpost(x->ls,val,x->val); 74 return qpost(x->rs,val,ans); 75 } 76 int main() 77 { 78 n=in();for (int i=1;i<=n;++i){ 79 opt=in();x=in(); 80 switch (opt){ 81 case 1:ins(rt,x);break; 82 case 2:del(rt,x);break; 83 case 3:printf("%d\n",qrank(rt,x));break; 84 case 4:printf("%d\n",qnum(rt,x));break; 85 case 5:printf("%d\n",qpre(rt,x,-1));break; 86 case 6:printf("%d\n",qpost(rt,x,-1));break; 87 } 88 }return 0; 89 }
无旋treap:
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define nl NULL 5 using namespace std; 6 inline int in(){ 7 int x=0;bool f=0; char c; 8 for (;(c=getchar())<'0'||c>'9';f=c=='-'); 9 for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0'); 10 return f?-x:x; 11 } 12 inline int rd(){ 13 static int x=23333; 14 x^=x<<13,x^=x>>17,x^=x<<5;return x; 15 } 16 int n,opt,x; 17 struct treap{ 18 treap *ls,*rs; 19 int val,pri,siz; 20 treap(int val):val(val),pri(rd()),siz(1),ls(nl),rs(nl){} 21 inline void combine(){siz=(ls?ls->siz:0)+(rs?rs->siz:0)+1;} 22 }*rt; 23 typedef pair<treap*,treap*> droot; 24 inline int gsize(treap *x){return x?x->siz:0;} 25 treap *merge(treap *a,treap *b){ 26 if (!a) return b;if (!b) return a; 27 if (a->pri<b->pri){a->rs=merge(a->rs,b);a->combine();return a;} 28 else{b->ls=merge(a,b->ls);b->combine();return b;} 29 }//suppose a<=b 30 droot split(treap *x,int k){ 31 if (!x) return droot(nl,nl);droot y; 32 if (gsize(x->ls)>=k){y=split(x->ls,k);x->ls=y.second;x->combine();y.second=x;} 33 else{y=split(x->rs,k-gsize(x->ls)-1);x->rs=y.first;x->combine();y.first=x;}return y; 34 } 35 inline int qnum(int v){ 36 droot x=split(rt,v-1),y=split(x.second,1); 37 treap *a=y.first;rt=merge(merge(x.first,a),y.second);return a->val; 38 } 39 inline int qrank(treap *x,int v){ 40 if (!x) return 0; 41 if (v<x->val) return qrank(x->ls,v); 42 return qrank(x->rs,v)+gsize(x->ls)+1; 43 } 44 inline void ins(int v){ 45 droot x=split(rt,qrank(rt,v)); 46 treap *a=new treap(v);rt=merge(merge(x.first,a),x.second); 47 } 48 inline void del(int v){ 49 droot x=split(rt,qrank(rt,v)-1),y=split(x.second,1); 50 treap *a=y.first;rt=merge(x.first,y.second);delete a;a=nl; 51 } 52 inline int qpre(int v){return qnum(qrank(rt,v-1));} 53 inline int qsuf(int v){return qnum(qrank(rt,v)+1);} 54 int main() 55 { 56 n=in();for (int i=1;i<=n;++i){ 57 opt=in();x=in();switch (opt){ 58 case 1:ins(x);break; 59 case 2:del(x);break; 60 case 3:printf("%d\n",qrank(rt,x-1)+1);break; 61 case 4:printf("%d\n",qnum(x));break; 62 case 5:printf("%d\n",qpre(x));break; 63 case 6:printf("%d\n",qsuf(x));break; 64 } 65 }return 0; 66 }
3.splay
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步