啊啊啊啊啊!!!!有关平衡树的知识补完了啊!!!!
treap。。。。二叉查找树和堆的结合体
treap基本操作:
push_up函数
//push_up函数
inline void push_up(int x){
size[x] = siz[son[x][0]] + siz[son[x][1]] + cnt[x];
}
旋转操作
//旋转操作
inline void rotate(int &x,int y){
int ii = son[x][y ^ 1];
son[x][y ^ 1] = son[ii][y];
son[ii][y] = x;
push_up(x);
push_up(ii);
x = ii;
}
插入
//插入节点
void ins(int &p,int x){
if(!p){
p = ++sz;
siz[p] = cnt[p] = 1;
key[p] = x;
rd[p] = rand();
return;
}
if(key[p] == x){
cnt[p]++;
siz[p]++;
return;
}
int d = (x > key[p]);
ins(son[p][d],x);
if(rd[p] < rd[son[p][d]]){
rotate(p,d^1);
}
push_up(p);
}
删除
//删除节点
void del(int &p,int x){
if(!p) return ;
if(x != key[p]){
del(son[p][x > key[p]],x);
}
else{
if(!son[p][0]&&!son[p][1]){
cnt[p]--;
siz[p]--;
if(cnt[p] == 0) p = 0;
}
else if(!son[p][0]&&son[p][1]){
rotate(p,0);//旋转过程?
del(son[p][0],x);
}
else if(son[p][0]&&!son[p][1]){
rotate(p,1);
del(son[p][1],x);
}
else if(son[p][0]&&son[p][1]){
int d = rd[son[p][0]] > rd[son[p][1]];
rotate(p,d);
del(son[p][d],x);
}
}
push_up(p);
}
查询排名
//查询排名
int get_rank(int p,int x){
if(!p) return 0;
if(key[p] == x) return siz[son[p][0]] + 1;
if(key[p] < x) return siz[son[p][0]] + cnt[p] + get_rank(son[p][1],x);
return get_rank(son[p][0],x);
}
按排名查询值
//按排名查询值
int find(int p,int x){
if(!p) return 0;
if(siz[son[p][0]] >= x) return find(son[p][0],x);
else if(siz[son[p][0]] + cnt[p] < x) return find(son[p][1],x - siz[son[p][0]] - cnt[p]);
else return key[p];
}
前驱
//前驱
int pre(int p,int x){
if(!p) return -inf;
if(key[p] >= x){
return pre(son[p][0],x)
}
else return max(key[p],pre(son[p][1],x));
}
后继
//后继
int suf(int p,int x){
if(!p) return inf;
if(key[p] <= x){
return suf(son[p][1],x);
}
else return min(key[p],suf(son[p][0],x));
}
旋转的过程还是不太明白,慢慢来吧!!!