各种平衡树板子
Posted passione-123456
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了各种平衡树板子相关的知识,希望对你有一定的参考价值。
Splay
#include <bits/stdc++.h> #define root e[0].son[1] using namespace std; int read() { int re = 0, f = 1; char ch = getchar(); while (ch < ‘0‘ || ch > ‘9‘) {if (ch == ‘-‘) f = -f; ch = getchar();} while (‘0‘ <= ch && ch <= ‘9‘) {re = re * 10 + ch - ‘0‘; ch = getchar();} return re * f; } const int N = 1e5 + 3; const int INF = 1e7 + 3; int n, cnt; struct node{ int v,recy,sum;//Ȩֵ Öظ´¸öÊý ×ÓÊ÷×ܸöÊý int fa,son[2];//µù ¶ù×Ó }e[N]; void update(int x){//¸üдóС e[x].sum=e[e[x].son[0]].sum+e[e[x].son[1]].sum+e[x].recy; } bool identify(int x){//È·¶¨¸¸×Ó¹Øϵ return e[e[x].fa].son[0]==x?0:1; } void connect(int x,int fa,int son){//ÈÏÇ× e[x].fa=fa,e[fa].son[son]=x; } void rotate(int x){//Ðýת int y=e[x].fa,z=e[y].fa; int zson=identify(y),yson=identify(x),xson=e[x].son[yson^1]; connect(xson,y,yson);connect(y,x,yson^1);connect(x,z,zson); update(y);update(x); return ; } void splay(int x,int to){//Òƶ¯xµ½toµÄλÖà int tofa=e[to].fa; while(tofa!=e[x].fa){ int fa=e[x].fa; int gfa=e[fa].fa; if(gfa!=tofa){ if(identify(x)!=identify(fa))rotate(x); else rotate(fa); } rotate(x); } if(to==root)root=x; } int newpoint(int v,int fa){//½¨Ðµã e[++cnt].fa=fa; e[cnt].v=v; e[cnt].sum=e[cnt].recy=1; return cnt; } void Insert(int v){//²åÈëȨֵΪvµÄµã int now=root; if(!root){root=newpoint(v,0);} else{ while(1){ e[now].sum++; if(e[now].v==v){e[now].recy++;splay(now,root);return;} int next=e[now].v<v?1:0; if(!e[now].son[next]){ e[now].son[next]=newpoint(v,now);splay(cnt,root);return; } now=e[now].son[next]; } } } int find(int v){//²éѯȨֵΪvµÄµãÔÚµÄλÖà int now=root; while(1){ if(e[now].v==v){splay(now,root);return now;} int next=e[now].v<v?1:0; if(!e[now].son[next])return 0; now=e[now].son[next]; } } void delet(int v){//ɾ³ýȨֵΪvµÄµã int now=find(v); if(!now)return; if(e[now].recy>1){e[now].recy--;e[now].sum--;} else{ if(!e[now].son[0]&&!e[now].son[1]){root=0;} else if(!e[now].son[0]){root=e[now].son[1];e[root].fa=0;} else{ int lef=e[now].son[0]; while(e[lef].son[1])lef=e[lef].son[1]; splay(lef,e[now].son[0]); connect(e[now].son[1],lef,1); connect(lef,0,1); update(lef); } } } int _rank(int v){//²éѯȨֵΪvµÄµãµÄÅÅÃû return e[e[find(v)].son[0]].sum+1; } int _kth(int k){//²éѯµÚxÃûµÄȨֵ int now=root; while(1){ int used=e[now].sum-e[e[now].son[1]].sum; if(e[e[now].son[0]].sum<k&&k<=used){splay(now,root);return e[now].v;} if(k<used){now=e[now].son[0];} else{k-=used;now=e[now].son[1];} } } int lower(int x){//Ç°Çý int now=root,val=-0x3f3f3f3f; while(now){ if(e[now].v<x)val=max(val,e[now].v); if(e[now].v<x)now=e[now].son[1]; else now=e[now].son[0]; } return val; } int upper(int x){//ºó¼Ì int now=root,val=0x3f3f3f3f; while(now){ if(e[now].v>x)val=min(val,e[now].v); if(e[now].v<=x)now=e[now].son[1]; else now=e[now].son[0]; } return val; } int main () { n = read(); while (n--) { int opt = read(); int x = read(); if (opt == 1) Insert(x); else if (opt == 2) delet(x); else if (opt == 3) printf("%d ", _rank(x)); else if (opt == 4) printf("%d ", _kth(x)); else if (opt == 5) printf("%d ", lower(x)); else if (opt == 6) printf("%d ", upper(x)); } return 0; }
Treap
#include<bits/stdc++.h> using namespace std; const int N=300010; int n,cnt,root; struct node{ int v,recy,sum;//Ȩֵ Öظ´¸öÊý ×ÓÊ÷×ܸöÊý int fa,son[2];//µù ¶ù×Ó int rk;//Ëæ»úÖµ }e[N]; void update(int x){//¸üдóС e[x].sum=e[e[x].son[0]].sum+e[e[x].son[1]].sum+e[x].recy; } void rotate(int &x,int next){//Ðýת int y=e[x].son[next^1]; e[x].son[next^1]=e[y].son[next];e[y].son[next]=x; update(x);update(y);x=y; } int newpoint(int v){//½¨Ðµã e[++cnt].v=v; e[cnt].sum=e[cnt].recy=1; e[cnt].rk=rand(); return cnt; } void Insert(int &x,int v){//²åÈëȨֵΪvµÄµã if(!x){x=newpoint(v);return;} if(e[x].v==v){e[x].recy++;e[x].sum++;return;} int next=e[x].v<v?1:0; Insert(e[x].son[next],v); if(e[x].rk<e[e[x].son[next]].rk)rotate(x,next^1); update(x); } void delet(int &x,int v){//ɾ³ýȨֵΪvµÄµã if(!x)return; if(v<e[x].v)delet(e[x].son[0],v); else if(v>e[x].v)delet(e[x].son[1],v); else { if(!e[x].son[0]&&!e[x].son[1]){ e[x].recy--; e[x].sum--; if(!e[x].recy)x=0; }else if(e[x].son[0]&&e[x].son[1]){ int next=e[e[x].son[0]].rk>e[e[x].son[1]].rk?1:0; rotate(x,next); delet(e[x].son[next],v); }else{ int next=!e[x].son[1]; rotate(x,next); delet(e[x].son[next],v); } } update(x); } int _rank(int x,int v){//²éѯȨֵΪvµÄµãµÄÅÅÃû if(!x)return 0; else if(e[x].v<v)return e[e[x].son[0]].sum+e[x].recy+_rank(e[x].son[1],v); else if(e[x].v>v)return _rank(e[x].son[0],v); else return e[e[x].son[0]].sum+1; } int _kth(int x,int k){//²éѯµÚkÃûµÄȨֵ if(!x)return 0; else if(e[e[x].son[0]].sum>=k)return _kth(e[x].son[0],k); else if(e[e[x].son[0]].sum+e[x].recy<k){ return _kth(e[x].son[1],k-e[e[x].son[0]].sum-e[x].recy); } else return e[x].v; } int lower(int x,int v){//Ç°Çý if(!x)return -0x3f3f3f3f; if(e[x].v>=v)return lower(e[x].son[0],v); else return max(e[x].v,lower(e[x].son[1],v)); } int upper(int x,int v){//ºó¼Ì if(!x)return 0x3f3f3f3f; if(e[x].v<=v)return upper(e[x].son[1],v); else return min(e[x].v,upper(e[x].son[0],v)); } int main(){ scanf("%d",&n); for (int i=0;i<n;++i) { int opt,x; scanf("%d%d",&opt,&x); if (opt==1) Insert(root,x); else if (opt==2) delet(root,x); else if (opt==3) printf("%d ",_rank(root,x)); else if (opt==4) printf("%d ",_kth(root,x)); else if (opt==5) printf("%d ",lower(root,x)); else if (opt==6) printf("%d ",upper(root,x)); } return 0; }
以上是关于各种平衡树板子的主要内容,如果未能解决你的问题,请参考以下文章