FHQ_treap

上个月还在舔\(splay\)\(FHQ-treap\)太好打了吧真香

前言

还是建议先把\(splay\)学好再看,讲得会比较粗略(但该有的不会少),或者左转其他文章

\(FHQ-treap\)是一种常数小同时好打的平衡树

其实就是利用附加权值\((heap)\)来维护树的平衡性(形状),同时树内有二叉搜索树性质

附加权值是随机给的,随机情况下使得树比较平衡,达到均摊\(log\)级别

合并

把两棵树\((A,B)\)合并起来,其中\(A\)树的所有值\(<B\)树的所有值

我们在维护附加权值\((heap)\)的同时实现合并,由于大小关系的前提比较好做

    int Merge(int x,int y){
        if(!x || !y) return x|y;
        Pushdown(x),Pushdown(y);
        if(heap[x] < heap[y]){
            son[x][1]=Merge(son[x][1],y); Update(x); return x;
        }else{
            son[y][0]=Merge(x,son[y][0]); Update(y); return y;
        }
    }

分裂

分裂有两种分裂,按值分与按排名分,传一个参数\(x\)进去把原树分成两棵树

即关键字\(≤x\)的一棵,剩下结点为另一棵

按排名分:

    void Split_r(int now,int k,int &x,int &y){
        if(!now) return (void)(x=y=0);
        Pushdown(now);
        if(size[son[now][0]]<k)
            x=now, Split_r(son[now][1], k-size[son[now][0]]-1, son[x][1], y), 
            Update(x), Update(y);
        else
            y=now, Split_r(son[now][0], k, x, son[y][0]), 
            Update(x), Update(y);
    }

操作区间

需要\((l,r)\)这个区间,分裂成\(a(1,l-1),b(l,r),c(r+1,n)\),把标记传进\(b\),然后再合并

总结

以上三个操作就是\(FHQ-treap\)的核心,做些题目去理解吧

转载于:https://www.cnblogs.com/y2823774827y/p/10321171.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值