[数据结构]FHQ-Treap】的更多相关文章

FHQ Treap是什么? FHQ Treap,又名无旋Treap,是一种不需要旋转的平衡树,是范浩强基于Treap发明的.FHQ Treap具有代码短,易理解,速度快的优点.(当然跟红黑树比一下就是--)至少它在OI中算是很优秀的数据结构了. 前置知识: C++ 二叉搜索树的基本性质,下面会讲 二叉堆 二叉搜索树的基本性质 很简单,就这几个. 在二叉搜索树中,每个结点都满足左子树的结点的值都小于等于自己的值,右子树的结点的值都大于自己的值,左右子树也是二叉搜索树. 中序遍历二叉搜索树可以得到一…
首先说一下, 这个东西可以搞一切bst,treap,splay所能搞的东西 pre 今天心血来潮, 想搞一搞平衡树, 先百度了一下平衡树,发现正宗的平衡树写法应该是在二叉查找树的基础上加什么左左左右右左右右的旋转之类的, 思路比较好理解,但是 代码量........ 一看就头大,, 然后,在洛谷翻题解的时候无意间看到了远航之曲发的一篇非常短小精悍的题解, 于是就学了一下 FHQ Treap 这个东西的学名应该是叫做fhq treap,应该是treap的强化版. 整个数据结构中只有两个操作: 1.…
今天上午学了一下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…
1.BST二叉搜索树 顾名思义,它是一棵二叉树. 它满足一个性质:每一个节点的权值大于它的左儿子,小于它的右儿子. 当然不只上面那两种树的结构. 那么根据性质,可以得到该节点左子树里的所有值都比它小,右子树的都比它大. 而平衡树都是基于BST的. 为什么叫做平衡树?对于数的操作可能会破坏BST的性质,这时会进行另外的操作,保持它的性质. 为什么要用BST?对于一棵BST,每一次的操作,都相当于进行一次二分,时间复杂度可以降到log级别. 这里写的是两个常用的平衡树. 2.Splay splay树…
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…
Preface 关于那些比较基础的平衡树我想我之前已经介绍的已经挺多了. 但是像Treap,Splay这样的旋转平衡树码亮太大,而像替罪羊树这样的重量平衡树却没有什么实际意义. 然而类似于SBT,AVL,RBT这些高级的乱搞平衡树无论时思想还是码量都让人难以接受. 而且在许多复杂的问题中需要维护区间,但是Splay的维护区间对于我这个蒟蒻来说实在是学不会. 许多的原因综合起来,在加上CJJ dalao的偶然安利,我便结识了神奇的FHQ Treap,一眼本命平衡树的感觉. 所以NOIP结束以后立马…
FHQ treap 的整理 treap = tree + heap,即同时满足二叉搜索树和堆的性质. 为了使树尽可能的保证两边的大小平衡,所以有一个key值,使他满足堆得性质,来维护树的平衡,key值是随机的. treap有一般平衡树的功能,前驱.后继.第k大.查询排名.插入.删除.也比较好写 但是对于区间上的问题是不能做的,例如 区间增减 区间求最值 区间反转(倒序) 区间移动(把一段剪切.粘贴) (splay是可以做的) 但是有一种神奇的数据结构,即可以满足treap的功能,也可以区间上进行…
听说很对劲的太刀流不止会splay一种平衡树,并不对劲的片手流为了反驳他,并与之针锋相对,决定学学高端操作. 很对劲的太刀流-> 据说splay常数极大,但是由于只知道splay一种平衡树能对序列进行操作,或者进行分裂合并,还不能不写它. 那么常数略小的treap能否对序列操作或者分裂合并呢?想必是能的. 这就是fhq大神的可分裂与合并的treap(据说国家队人手一个自创算法?那必须的不然ctsc论文答辩怎么过). 它并没有比treap多出什么,反而省了好多事.核心操作只有split和merge…
.....好吧....最后一篇学习笔记的flag它倒了..... 好吧,这篇笔记也鸽了好久好久了... 比赛前刷模板,才想着还是补个坑吧... FHQ,这个神仙(范浩强大佬),发明了这个神仙的数据结构, 首先,本篇博客使用洛谷普通平衡树为背景,即 查找前驱 查找后记 查找kth的数 查找k的排名 插入一个数 删除一个数 FHQ treap,是一个treap,它还是和treap一样,是tree+heap,所以它也有一个键值维护堆的性质. 它可以干任何treap和Splay能干的事. 它的实现主要由…
前言 好久没码过平衡树了! 这次在闪指导的指导下学会了\(FHQ\ Treap\),一方面是因为听说它可以可持久化,另一方面则是因为听说它是真的好写. 简介 \(FHQ\ Treap\),又称作非旋\(Treap\). 其实在我看来,它与\(Treap\)的共同点也只有都借助了随机键值来维护平衡. 具体实现起来,两者真是大为不同. 不过,为助于理解,还是在这里贴上\(Treap\)的博客吧:简析平衡树(二)--Treap. \(FHQ\ Treap\)的核心操作 其他内容我也就不多说了,下面就从…
[BZOJ 3173] [TJOI 2013] 最长上升子序列(fhq treap) 题面 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? 分析 这题有几个重要性质: 第一个性质是,插入的数的大小是递增的.我们插入第i个数后的答案,为以当前序列中的数为结尾的LIS长度的最大值,而根据当前序列中的数都在[1,i]内,们可以维护以值v为结尾的LIS长度len[i],那么第i次插入后的答案就是\…
P3835 [模板]可持久化平衡树 题意 题目背景 本题为题目普通平衡树的可持久化加强版. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本): 插入\(x\)数 删除\(x\)数(若有多个相同的数,因只删除一个,如果没有请忽略该操作) 查询\(x\)数的排名(排名定义为比当前数小的数的个数\(+1\).若有多个相同的数,因输出最小的排名) 查询排名为x的数 求\(x\)的前驱(前驱定义为小于\(x\),且最大的数,如不存在输出\(-2…
FHQ Treap FHQ Treap (%%%发明者范浩强年年NOI金牌)是一种神奇的数据结构,也叫非旋Treap,它不像Treap zig zag搞不清楚(所以叫非旋嘛),也不像Splay完全看不懂,而且它能完成Treap与Splay能完成的所有事,代码短,理解也容易. 基本操作 FHQ Treap和Treap很像,都是给每个节点一个随机的权值,使它满足堆的性质.建议先了解Treap(没必要实现,懂得原理即可).不过,如果有两个节点值相同,FHQ Treap不会用一个数组cnt记录个数,而是…
传送门: 解题思路: 算是补坑了,这题除了Invert以外就可以树剖线段树解决了. 考虑Invert操作,延续先前树链剖分的做法,考虑先前算法的瓶颈. 最暴力的方法是暴力交换权值,然而这种方法忽略了当前树链剖分序的一个性质,那就是很多部分的树链是连续的,而且仅有$O(\lg n)$个区间. 考虑只有一个区间的做法,就很显然是区间翻转(这个不会搞的话你是怎么做到这道题的),于是,由于区间个数并不多,我们大胆猜想:正确的解法就是考虑翻如何转这些不连续区间 由于链区间具有一定的连续性,且我们需要翻转其…
新学习了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拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况是一项相当复杂的工作.由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题.经济管理学上定义了一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大…
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函数返回的值应当是合并完后的根节点. 分裂分为两种,排名和权值.然而我认为它们本质上是一样的.对于权…
原理 以随机数维护平衡,使树高期望为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…
一.简介 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]; 操作 最基本的操作 其实都不应该叫做…
FHQ Treap,又称无旋treap,一种不基于旋转机制的平衡树,可支持所有有旋treap.splay等能支持的操作(只有在LCT中会比splay复杂度多一个log).最重要的是,它是OI中唯一一种支持可持久化的平衡树. 以下只提供题表与代码,不提供教程. 1.[BZOJ3224]普通平衡树 FHQ Treap的应用一:基础平衡树操作模板题. 由于merge.split和树高是$O(\log n)$的,所以所有基础操作都是$O(\log n)$的. #include<cstdio> #inc…
目录 碎碎念 点一下 注意!!! 模板 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…
终于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的特点是实现简单,…
Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 2363   Accepted: 881 Description Like so many others, the cows have developed very haughty tastes and will no longer graze on just any grass. Instead, Farmer John must purchase gourmet orga…
传送门 看了一圈,好像真的没什么用指针的呢.. 明明觉得指针很好看(什么??你说RE???听不见听不见) 其实我觉得用数组的话不RE直接WA调起来不是更困难嘛,毕竟通过gdb还可以知道哪里RE,WA就不知道咋回事了,是不是很有道理,虽然我还是调了几小时 我写的是fhq treap,核心是split和merge操作,思想高赞dalao都讲得很清楚,我语文弱渣就不班门弄斧了,主要是想提供一个指针版的参考吧QAQ 我真的是一整天都在搞分裂(split),有种要进入七月枪毙名单的赶脚,慌张.jpg #i…
题面 传送门 题解 \(FHQ\ Treap\)比起\(Splay\)还是稍微好写一点--就是老是忘了要下穿标记-- //minamoto #include<bits/stdc++.h> #define R register #define inline __inline__ __attribute__((always_inline)) #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i) #define fd(i,a,b) for(R i…