FHQ Treap树

Treap树简介

Treap是一个合成词,Treap=Tree+Heap,顾名思义,它是具有堆性质的树,它的本质还是BST(二叉查找树),但因为引入了随机的权值使其在概率期望上达到了 l o g 2 n log_2{n} log2n的复杂度。

Treap树的维护有旋转法和FHQ两种方式,FHQ是近年来逐渐流行的,其编码更加简单且可以解决区间翻转和区间移动等问题。

FHQ Treap树例题

P3391 【模板】文艺平衡树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 10;
struct Node {
    int ls, rs;
    int pri; //权值
    int num;//储存值
    int size;//子树大小
    int lazy;
} t[N];
int cnt = 0,root=0;
void pushdown(int x){
    if(t[x].lazy){
        swap(t[x].ls,t[x].rs);
        t[t[x].ls].lazy^=1;
        t[t[x].rs].lazy^=1;
        t[x].lazy=0;
    }
}
void NewNode(int x) {
    ++cnt;
    t[cnt].ls = t[cnt].rs = t[cnt].lazy = 0;
    t[cnt].size = 1;
    t[cnt].num = x;
    t[cnt].pri = rand();
}
void Update(int x){
    t[x].size=t[t[x].ls].size+t[t[x].rs].size+1;
}
int Merge(int L,int R){
    if(L==0||R==0)
        return L+R;
    if(t[L].pri>t[R].pri) {
        pushdown(L);
        t[L].rs = Merge(t[L].rs, R);
        Update(L);
        return L;
    }
    else {
        pushdown(R);
        t[R].ls = Merge(L, t[R].ls);
        Update(R);
        return R;
    }

}
void inorder(int u){
    if(u==0)
        return;
    pushdown(u);
    inorder(t[u].ls);
    cout<< t[u].num << " ";
    inorder(t[u].rs);
}
void Split(int u,int x,int &L,int &R){
    if(u==0){
        L=R=0;
        return;
    }
    pushdown(u);

     if (t[t[u].ls].size+1<=x){
         L=u;
         Split(t[u].rs,x-(t[t[u].ls].size+1),t[L].rs,R);
     }
     else{
         R=u;
         Split(t[u].ls,x,L,t[R].ls);
     }
    Update(u);
}
int main() {
    srand(time(NULL));
    int m, n;
    cin >> m >> n;
    for(int i=1;i<=n;i++) {
        NewNode(i);
        root = Merge(root,cnt);
    }
    int l, r;
    int L,R,M;
    while (m--) {
        cin >> l >> r;
        Split(root,r,L,R);
        Split(L,l-1,L,M);
        t[M].lazy^=1;
        root= Merge(Merge(L,M),R);
    }
    inorder(root);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
可持久化splay是一种数据结构,它是对splay进行修改和查询的一种扩展。在传统的splay中,对的修改操作会破坏原有的结构,而可持久化splay则允许我们对进行修改、查询,并且可以保存修改后的每个版本的结构。 在可持久化splay中,我们不会直接对原进行修改,而是通过复制每个节点来创建新的版本。这样,每个版本都可以独立地修改和查询,保留了原有版本的结构和状态。每个节点保存了其左子和右子的引用,使得可以在不破坏原有版本的情况下进行修改和查询。 为了实现可持久化splay,我们可以使用一些技巧,比如引用中提到的哨兵节点和假的父节点和孩子节点。这些技巧可以帮助我们处理根节点的旋转和其他操作。 此外,可持久化splay还可以与其他数据结构相结合,比如引用中提到的可持久化线段。这种结合可以帮助我们解决更复杂的问题,比如区间修改和区间查询等。 对于可持久化splay的学习过程,可以按照以下步骤进行: 1. 理解splay的基本原理和操作,包括旋转、插入、删除和查找等。 2. 学习如何构建可持久化splay,包括复制节点、更新版本和保存历史版本等。 3. 掌握可持久化splay的常见应用场景,比如区间修改和区间查询等。 4. 深入了解与可持久化splay相关的其他数据结构算法,比如可持久化线段等。 在解决问题时,可以使用二分法来确定答案,一般称为二分答案。通过对答案进行二分,然后对每个答案进行检查,以确定最终的结果。这种方法可以应用于很多问题,比如引用中提到的在线询问问题。 综上所述,可持久化splay是一种对splay进行修改和查询的扩展,可以通过复制节点来创建新的版本,并且可以与其他数据结构相结合解决更复杂的问题。学习过程中可以按照一定的步骤进行,并且可以使用二分法来解决一些特定的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [[学习笔记]FHQ-Treap及其可持久化](https://blog.csdn.net/weixin_34283445/article/details/93207491)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [可持久化数据结构学习笔记](https://blog.csdn.net/weixin_30376083/article/details/99902410)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辰宝IWZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值