【DS】fhq Treap 复习

新建结点

int cnt,root;
inline int newnode(int val){
    fhq[++cnt].val=val;
    fhq[cnt].key=rand();
    fhq[cnt].size=1;
    return cnt;
}

按权分裂

void split(int now,int val,int &x,int &y){
    if(!now)x=y=0;
    else {
        if(fhq[now].val<=val){//小于等于val给左边(x),大于val给右边(y)
            x=now;
            split(fhq[now].r,val,fhq[now].r,y);
        }else {
            y=now;
            split(fhq[now].l,val,x,fhq[now].l);
        }
        update(now);
    }
}

按大小分裂

void split(int now,int sz,int &x,int &y){
   if(!now)x=y=0;
   else {
	if(fhq[now].tag)pushdown(now);
	if(fhq[ls].size<sz){// 小于size给左边(x),大于等于size给右边(y)
	   x=now;
	   split(rs,sz-fhq[ls].size-1,rs,y);
	}else {
	    y=now;
	    split(ls,sz,x,ls);
	}
	pushup(now);
    }
}

合并

int merge(int x,int y){//保证x子树比y子树的值小
    if(!x||!y)return x+y;
    if(fhq[x].key>fhq[y].key){//x的索引大于y的
        fhq[x].r=merge(fhq[x].r,y);
        //满足二叉堆和搜索数的性质,y子树在x子树的右下方
        update(x);return x;
    }else {//反之则反过来
        fhq[y].l=merge(x,fhq[y].l);
        update(y);return y;
    }
}

插入

inline void ins(int val,int x,int y){
    split(root,val,x,y);//按值分裂
    root=merge(merge(x,newnode(val)),y);//合并x,val,y三棵子树
}

删除

inline void del(int val,int x,int y,int z){
    split(root,val,x,z);//按val将整棵树分裂成x和z两棵子树
    split(x,val-1,x,y);//按val-1将x树分裂成x,y两棵子树
    //此时,y数上的点一定等于val
    y=merge(fhq[y].l,fhq[y].r);//删除掉根就好啦
    root=merge(merge(x,y),z);//将x,y,z合并
}

查 rank

inline void rank(int val,int x,int y){//查询值的排名
    split(root,val-1,x,y);//按照val-1分裂
    printf("%d\n",fhq[x].size+1);
    //此时x子树的值一定小于等于val-1,则其大小+1即为val的排名
    root=merge(x,y);//再合并回来!
}

前驱后继

inline void pre(int val,int x,int y){
    split(root,val-1,x,y);//按val-1分裂,则x子树的最右边即为前驱(x<=val-1)
    int now=x;
    while(fhq[now].r)now=fhq[now].r;
    printf("%d\n",fhq[now].val);
    root=merge(x,y);
}

inline void nxt(int val,int x,int y){
    split(root,val,x,y);//按val分裂,则y子树的最左边即为后继(y>val)
    int now=y;
    while(fhq[now].l)now=fhq[now].l;
    printf("%d\n",fhq[now].val);
    root=merge(x,y);
}
posted @ 2022-10-24 08:48  RuntimeErr  阅读(31)  评论(0编辑  收藏  举报