可持久化treap(FHQ treap)】的更多相关文章

P3835 [模板]可持久化平衡树 题意 题目背景 本题为题目普通平衡树的可持久化加强版. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本): 插入\(x\)数 删除\(x\)数(若有多个相同的数,因只删除一个,如果没有请忽略该操作) 查询\(x\)数的排名(排名定义为比当前数小的数的个数\(+1\).若有多个相同的数,因输出最小的排名) 查询排名为x的数 求\(x\)的前驱(前驱定义为小于\(x\),且最大的数,如不存在输出\(-2…
传送门 看了一圈,好像真的没什么用指针的呢.. 明明觉得指针很好看(什么??你说RE???听不见听不见) 其实我觉得用数组的话不RE直接WA调起来不是更困难嘛,毕竟通过gdb还可以知道哪里RE,WA就不知道咋回事了,是不是很有道理,虽然我还是调了几小时 我写的是fhq treap,核心是split和merge操作,思想高赞dalao都讲得很清楚,我语文弱渣就不班门弄斧了,主要是想提供一个指针版的参考吧QAQ 我真的是一整天都在搞分裂(split),有种要进入七月枪毙名单的赶脚,慌张.jpg #i…
简介:     Treap,一种表现优异的BST 优势:     其较于AVL.红黑树实现简单,浅显易懂     较于Splay常数小,通常用于树套BST表现远远优于Splay     或许有人想说SBT,SBT我没有实现过,据说比较快     但是SBT.Splay以及旋转版Treap等BST都不可以比较方便地实现‘可持久化操作   Treap=Tree+Heap     Treap是一颗同时拥有二叉搜索树和堆性质的一颗二叉树     Treap有两个关键字,在这里定义为:         1…
题目链接 对每次Merge(),Split()时产生的节点都复制一份(其实和主席树一样).时间空间复杂度都为O(qlogq).(应该更大些 因为rand()?内存真的爆炸..) 对于无修改的操作实际上是可以直接赋值的,因为以后也不会去改当前树,只需要查询:修改时自会复制新节点. 虽然操作3.4.5.6不会改变原树,但是Split()会改变树的形态,所以仍要新建节点,但根节点不需要Merge(). #include <cstdio> #include <cctype> #includ…
https://www.luogu.org/problemnew/show/P3369 知识点:1.拆分split,合并merge 2.split,merge要点:通过传址调用来简便代码 3.记得root = merge(xxxxx,xxxxx); 2 wrong in code #include <bits/stdc++.h> #define M 200002 using namespace std; int tot = ; int val[M],rd[M]; int ch[M][]; in…
FHQ treap 的整理 treap = tree + heap,即同时满足二叉搜索树和堆的性质. 为了使树尽可能的保证两边的大小平衡,所以有一个key值,使他满足堆得性质,来维护树的平衡,key值是随机的. treap有一般平衡树的功能,前驱.后继.第k大.查询排名.插入.删除.也比较好写 但是对于区间上的问题是不能做的,例如 区间增减 区间求最值 区间反转(倒序) 区间移动(把一段剪切.粘贴) (splay是可以做的) 但是有一种神奇的数据结构,即可以满足treap的功能,也可以区间上进行…
Splay Splay(伸展树)是一种二叉搜索树. 其复杂度为均摊\(O(n\log n)\),所以并不可以可持久化. Splay的核心操作有两个:rotate和splay. pushup: 上传信息,比如区间和.子树大小... rotate: rotate实现把一个节点\(x\)转到它的父亲\(y\)的位置. 假设\(x\)是\(y\)的左儿子. 那么旋转完之后,\(y\)就会变成\(x\)的右儿子. 那么\(x\)原来的右儿子的地方就被占了,我们就把它放到\(y\)的左儿子. 实际上就是把\…
FHQ Treap FHQ Treap (%%%发明者范浩强年年NOI金牌)是一种神奇的数据结构,也叫非旋Treap,它不像Treap zig zag搞不清楚(所以叫非旋嘛),也不像Splay完全看不懂,而且它能完成Treap与Splay能完成的所有事,代码短,理解也容易. 基本操作 FHQ Treap和Treap很像,都是给每个节点一个随机的权值,使它满足堆的性质.建议先了解Treap(没必要实现,懂得原理即可).不过,如果有两个节点值相同,FHQ Treap不会用一个数组cnt记录个数,而是…
2021.12.08 平衡树--FHQ Treap http://www.yhzq-blog.cc/fhqtreapzongjie/ https://www.cnblogs.com/zwfymqz/p/7151959.html 1. FHQ Treap FHQ Treap与Treap一样,都有关键码和优先级.关键码满足二叉搜索树的性质--左子树的关键码小于根节点,右子树的关键码大于根节点.优先级满足堆的性质--所有子树的优先级均大于或小于根节点的优先级的值. 因此,本篇博客默认优先级越大越优.…
FHQ Treap,又称无旋treap,一种不基于旋转机制的平衡树,可支持所有有旋treap.splay等能支持的操作(只有在LCT中会比splay复杂度多一个log).最重要的是,它是OI中唯一一种支持可持久化的平衡树. 以下只提供题表与代码,不提供教程. 1.[BZOJ3224]普通平衡树 FHQ Treap的应用一:基础平衡树操作模板题. 由于merge.split和树高是$O(\log n)$的,所以所有基础操作都是$O(\log n)$的. #include<cstdio> #inc…
原理 以随机数维护平衡,使树高期望为logn级别 不依靠旋转,只有两个核心操作merge(合并)和split(拆分) 因此可持久化 先介绍变量 ; int n; struct Node { int val,key,siz; //权值,随机权值,子树大小 ]; //左右儿子(0左1右) void res() { //清空该节点(用于删除) son[]=son[]=siz=val=key=; } } tree[N]; int ins; int mem[N],inm; //内存回收池 int root…
Preface 关于那些比较基础的平衡树我想我之前已经介绍的已经挺多了. 但是像Treap,Splay这样的旋转平衡树码亮太大,而像替罪羊树这样的重量平衡树却没有什么实际意义. 然而类似于SBT,AVL,RBT这些高级的乱搞平衡树无论时思想还是码量都让人难以接受. 而且在许多复杂的问题中需要维护区间,但是Splay的维护区间对于我这个蒟蒻来说实在是学不会. 许多的原因综合起来,在加上CJJ dalao的偶然安利,我便结识了神奇的FHQ Treap,一眼本命平衡树的感觉. 所以NOIP结束以后立马…
一.简介 fhq treap 与一般的treap主要有3点不同 1.不用旋转 2.以merge和split为核心操作,通过它们的组合实现平衡树的所有操作 3.可以可持久化 二.核心操作 代码中val表示节点权值,pri表示节点的优先级,维护小根堆 1.split 将1个treap分裂为两个treap 分裂主要有两种:以权值k作为分界点.以位置k作为分界点 ①以权值k作为分界点 设原来的treap根节点为root,分裂后的<=k的treap A 的根节点为x,>k的treap B 的根节点为y…
序 今天心血来潮,来学习一下fhq treap(其实原因是本校有个OIer名叫fh,当然不是我) 简介 fhq treap 学名好像是"非旋转式treap及可持久化"...听上去怪怪的.其实就是可以代替LCT.BST等等码量很高的东东. 定义 struct node{ int son[2],val,rand_val,sz;//很好理解,从左到右依次为:左右儿子编号,权值,随机权值(用处后面会讲),此节点下(包括此节点)共有多少个节点 }tr[N]; 操作 最基本的操作 其实都不应该叫做…
听说很对劲的太刀流不止会splay一种平衡树,并不对劲的片手流为了反驳他,并与之针锋相对,决定学学高端操作. 很对劲的太刀流-> 据说splay常数极大,但是由于只知道splay一种平衡树能对序列进行操作,或者进行分裂合并,还不能不写它. 那么常数略小的treap能否对序列操作或者分裂合并呢?想必是能的. 这就是fhq大神的可分裂与合并的treap(据说国家队人手一个自创算法?那必须的不然ctsc论文答辩怎么过). 它并没有比treap多出什么,反而省了好多事.核心操作只有split和merge…
前言 好久没码过平衡树了! 这次在闪指导的指导下学会了\(FHQ\ Treap\),一方面是因为听说它可以可持久化,另一方面则是因为听说它是真的好写. 简介 \(FHQ\ Treap\),又称作非旋\(Treap\). 其实在我看来,它与\(Treap\)的共同点也只有都借助了随机键值来维护平衡. 具体实现起来,两者真是大为不同. 不过,为助于理解,还是在这里贴上\(Treap\)的博客吧:简析平衡树(二)--Treap. \(FHQ\ Treap\)的核心操作 其他内容我也就不多说了,下面就从…
1.BST二叉搜索树 顾名思义,它是一棵二叉树. 它满足一个性质:每一个节点的权值大于它的左儿子,小于它的右儿子. 当然不只上面那两种树的结构. 那么根据性质,可以得到该节点左子树里的所有值都比它小,右子树的都比它大. 而平衡树都是基于BST的. 为什么叫做平衡树?对于数的操作可能会破坏BST的性质,这时会进行另外的操作,保持它的性质. 为什么要用BST?对于一棵BST,每一次的操作,都相当于进行一次二分,时间复杂度可以降到log级别. 这里写的是两个常用的平衡树. 2.Splay splay树…
前面我们对平衡树有了个大概的了解 关于 Treap Treap=Binary Search Tree + Heap 二叉搜索树 + 二叉堆(一般是小根堆) Treap 每一个节点有两个值 一个值是平衡树的值,一个值是随机的(用于堆来保持平衡) 二叉堆的性质使其保持平衡 关于 FHQ Treap 这个名字来源很简单: FHQ 大佬发明的 Treap 普通的 Treap 是通过旋转来平衡的 而 FHQ Treap 是通过合并.分裂来维护的 核心操作 约定 变量名 作用 sz[] 存储以某个节点为根的…
新学习了fhq treap,厉害了 先贴个神犇的版, from memphis /* Treap[Merge,Split] by Memphis */ #include<cstdio> #include<algorithm> #include<cstring> #include<ctime> using namespace std; #define maxn 2000005 #define rep(i,x,y) for(int i=x;i<=y;++i…
Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况是一项相当复杂的工作.由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题.经济管理学上定义了一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大…
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval. In…
1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 15112  Solved: 4996[Submit][Status][Discuss] Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一条命令,格式参见问题描述中的表格.任何时刻数列中最多含有500 000个数,…
话说天下大事,就像fhq treap —— 分久必合,合久必分 简单讲一讲.非旋treap主要依靠分裂和合并来实现操作.(递归,不维护fa不维护cnt) 合并的前提是两棵树的权值满足一边的最大的比另一边最小的还小.因此时合并时只需要维护键值的堆性质即可.这样每一次比较根节点,如果x比y小那么y直接接到x的右子树即可(需要满足权值的平衡树性质):否则的话只需要反过来,把x接到y的左子树上.merge函数返回的值应当是合并完后的根节点. 分裂分为两种,排名和权值.然而我认为它们本质上是一样的.对于权…
首先说一下, 这个东西可以搞一切bst,treap,splay所能搞的东西 pre 今天心血来潮, 想搞一搞平衡树, 先百度了一下平衡树,发现正宗的平衡树写法应该是在二叉查找树的基础上加什么左左左右右左右右的旋转之类的, 思路比较好理解,但是 代码量........ 一看就头大,, 然后,在洛谷翻题解的时候无意间看到了远航之曲发的一篇非常短小精悍的题解, 于是就学了一下 FHQ Treap 这个东西的学名应该是叫做fhq treap,应该是treap的强化版. 整个数据结构中只有两个操作: 1.…
目录 碎碎念 点一下 注意!!! 模板 fhq treap 碎碎念 我咋感觉合并这么像左偏树呢 ps:难道你们的treap都是小头堆的吗 fhq真的是神人 现在看以前学的splay是有点恶心,尤其是压行压不过fhqtreap 点一下 fhq treap主要操作就俩 拆(merge)和合(split) 其他操作都是基于这俩操作(拆拆合合,合拆合拆,拆了又和,合了又拆) 合并操作merge 把两颗树合并成一颗 这里的两颗树x,y,满足x树小于y树 因为要保证堆的性质 if(!x||!y) retur…
思路: 1. 此处的fhq treap的分裂是按照权值分裂然后插入的.将小于k的分为一棵子树,大于等于k的分为另一棵子树. 2. 删除的时候只要将大于等于min的分裂到以root为根的树中,另一部分不用管,扔掉. 3. 维护一个加标记,注意不要忘记某个地方的pushdown和pushup 其他就是fhq treap的基本操作了 #include<bits/stdc++.h> using namespace std; #define ls a[x].l #define rs a[x].r ; i…
今天上午学了一下fhq treap感觉真的很好用啊qwq 变量名解释: \(size[i]\)表示以该节点为根的子树大小 \(fix[i]\)表示随机权值 \(val[i]\)表示该节点的值 \(ch[i][0]\)表示该节点的左儿子 \(ch[i][1]\)表示该节点的右儿子 更新操作:update inline void update(int x) {size[x]=1+size[ch[x][0]]+size[ch[x][1]];} 就是用自己的左右子树更新自己. 新建节点:new_node…
终于A了这题...这题还是很好...但是我太菜...重构了三遍qwq FHQ Treap大法好!qwq...~~ Ins:直接拿输入造一棵树,把原来的树split成[1,pos],[pos+1,n],然后merge三棵树: Del:把要删的区间split出来,merge他两边的树,记着要回收内存: Mk-Same:把要改的区间split出来,打上标记,更新这棵树根的信息(见cover(x,v)),再merge回去: Rev:把要翻转的区间split出来,打上标记,更新这棵树根的信息(见rever…
这道题要求区间反转...好东西.. 对于Splay:把l-1旋到根,把r+1旋到根的右儿子,这样r+1的左儿子就是整个区间了,然后对这个区间打个tg 注意要插-Inf和Inf到树里面,防止越界,坐标要+1 #include<cstdio> #include<iostream> #define R register int using namespace std; ,Inf=0x3f3f3f3f; inline int g() { R ret=,fix=; register :fix…
今天翻了翻其他大佬的博客,发现自己有些...颓废... 有必要洗心革面,好好学习 序:正常的BST有可能退化,成为链,大大降低效率,所以有很多方法来保持左右size的平衡,本文将简单介绍Treap,Splay,替罪羊,FHQ Treap: 另:代码都是普通平衡树 1.Treap 树堆,在数据结构中也称Treap,是指有一个随机附加域满足堆的性质的二叉搜索树,其结构相当于以随机数据插入的二叉搜索树.其基本操作的期望时间复杂度为O(logn).相对于其他的平衡二叉搜索树,Treap的特点是实现简单,…