可持久化fhq-treap学习笔记
可持久化fhq-treap----- 支持查询历史版本的非旋treap
luogu扣图:
先看看为啥他可以可持久化
由于fhq-Treap是没有旋转操作的
所以每次操作后的其它没有操作的节点间的关系不变
而有旋转平衡树是要改变的,所以就不大能进行可持久化了
过程
回想,主席树的方法:
每次用log的内存记录一次操作
这可持久平衡树也一样
每次merge或者split都新开节点记录路径
路径是log级的,所以内存也在nlogn的级别(当然不是nlog,是操作log)
还是用结构体吧,容易赋值
其实也就是加了几句话
其实也就是和主席树差不多
其实也没啥说的,看代码去吧
别的
SovietPower:一点(很小的)优化? 操作3.4.5.6都不会改原树,root[i]=root[ver]可以直接赋值,不需要再Merge了
xx:为什么
SovietPower:你的合并操作的内存都是新开的,但你这一次操作(是opt的操作辣)是没有改变任何值,所以你直接用上一次的就好,拆开的内存不用管就好
注意&&出错&&吐槽
我们截取merge函数的一部分
if(e[x].pri<e[y].pri) {
int p=++cnt;
e[p]=e[x];
rs(p)=merge(rs(p),y);
pushup(p);
return p;
}
}
那是不是可以写成
if(e[x].pri<e[y].pri) {
int p=++cnt;
e[p]=e[x];
rs(p)=merge(rs(p),y);
pushup(p);
return p;
}
当然是不对的啊,你还要递归呢,cnt当然要变化了
这数组模拟内存浪费的有点多呀,指针应该就没这毛病了,不过我还是学不下去指针233
模板->luoguP3835代码
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#define ls(x) e[x].ls
#define rs(x) e[x].rs
#define FOR(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int maxn=500007;
const int inf=0x7fffffff;
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
struct node {
int ls,rs,size,val,pri;
}e[maxn*50];
int cnt,rt[maxn*50];
void pushup(int x) {
e[x].size=e[ls(x)].size+e[rs(x)].size+1;
}
int make_edge(int x) {
e[++cnt].val=x;
e[cnt].size=1;
e[cnt].pri=rand();
return cnt;
}
int merge(int x,int y) {
if(!x||!y) return x+y;
if(e[x].pri<e[y].pri) {
int p=++cnt;
e[p]=e[x];
rs(p)=merge(rs(p),y);
pushup(p);
return p;
}
else {
int p=++cnt;
e[p]=e[y];
ls(p)=merge(x,ls(p));
pushup(p);
return p;
}
}
void split(int now,int k,int &x,int &y) {
if(!now) x=y=0;
else {
if(e[now].val<=k) {
e[x=++cnt]=e[now];
split(rs(now),k,rs(x),y);
pushup(x);
}
else {
e[y=++cnt]=e[now];
split(ls(now),k,x,ls(y));
pushup(y);
}
}
}
inline int k_th(int now,int k) {
while(233) {
if(k==e[ls(now)].size+1) return now;
if(k<=e[ls(now)].size) now=ls(now);
else k-=e[ls(now)].size+1,now=rs(now);
}
}
int main() {
int n=read(),x,y,z;
FOR(i,1,n) {
int tim=read(),opt=read(),a=read();
rt[i]=rt[tim];
if(opt==1) {
split(rt[i],a,x,y);
rt[i]=merge(merge(x,make_edge(a)),y);
} else if(opt==2) {
split(rt[i],a,x,z);
split(x,a-1,x,y);
y=merge(ls(y),rs(y));
rt[i]=merge(merge(x,y),z);
} else if(opt==3) {
split(rt[i],a-1,x,y);
printf("%d\n",e[x].size+1);
rt[i]=merge(x,y);
} else if(opt==4) {
printf("%d\n",e[k_th(rt[i],a)].val);
} else if(opt==5) {
split(rt[i],a-1,x,y);
if(e[x].size) {
printf("%d\n",e[k_th(x,e[x].size)].val);
rt[i]=merge(x,y);
}
else printf("%d\n",-inf);
} else {
split(rt[i],a,x,y);
if(e[y].size) {
printf("%d\n",e[k_th(y,1)].val);
rt[i]=merge(x,y);
}
else printf("%d\n",inf);
}
}
return 0;
}
可持久化fhq-treap学习笔记的更多相关文章
- fhq treap 学习笔记
序 今天心血来潮,来学习一下fhq treap(其实原因是本校有个OIer名叫fh,当然不是我) 简介 fhq treap 学名好像是"非旋转式treap及可持久化"...听上去怪 ...
- FHQ treap学习(复习)笔记
.....好吧....最后一篇学习笔记的flag它倒了..... 好吧,这篇笔记也鸽了好久好久了... 比赛前刷模板,才想着还是补个坑吧... FHQ,这个神仙(范浩强大佬),发明了这个神仙的数据结构 ...
- 左偏树 / 非旋转treap学习笔记
背景 非旋转treap真的好久没有用过了... 左偏树由于之前学的时候没有写学习笔记, 学得也并不牢固. 所以打算写这么一篇学习笔记, 讲讲左偏树和非旋转treap. 左偏树 定义 左偏树(Lefti ...
- treap学习笔记
treap是个很神奇的数据结构. 给你一个问题,你可以解决它吗? 这个问题需要treap这个数据结构. 众所周知,二叉查找树的查找效率低的原因是不平衡,而我们又不希望用各种奇奇怪怪的旋转来使它平衡,那 ...
- fhq treap抄袭笔记
目录 碎碎念 点一下 注意!!! 模板 fhq treap 碎碎念 我咋感觉合并这么像左偏树呢 ps:难道你们的treap都是小头堆的吗 fhq真的是神人 现在看以前学的splay是有点恶心,尤其是压 ...
- Treap + 无旋转Treap 学习笔记
普通的Treap模板 今天自己实现成功 /* * @Author: chenkexing * @Date: 2019-08-02 20:30:39 * @Last Modified by: chenk ...
- [Treap][学习笔记]
平衡树 平衡树就是一种可以在log的时间复杂度内完成数据的插入,删除,查找第k大,查询排名,查询前驱后继以及其他许多操作的数据结构. Treap treap是一种比较好写,常数比较小,可以实现平衡树基 ...
- Treap-平衡树学习笔记
平衡树-Treap学习笔记 最近刚学了Treap 发现这种数据结构真的是--妙啊妙啊~~ 咳咳.... 所以发一发博客,也是为了加深蒟蒻自己的理解 顺便帮助一下各位小伙伴们 切入正题 Treap的结构 ...
- 「学习笔记」 FHQ Treap
FHQ Treap FHQ Treap (%%%发明者范浩强年年NOI金牌)是一种神奇的数据结构,也叫非旋Treap,它不像Treap zig zag搞不清楚(所以叫非旋嘛),也不像Splay完全看不 ...
- 「FHQ Treap」学习笔记
话说天下大事,就像fhq treap —— 分久必合,合久必分 简单讲一讲.非旋treap主要依靠分裂和合并来实现操作.(递归,不维护fa不维护cnt) 合并的前提是两棵树的权值满足一边的最大的比另一 ...
随机推荐
- mysql数据库的相关练习题及答案
表结构示意图: 表结构创建语句: class表创建语句 create table ) not null)engine=innodb default charset=utf8; student表创建语句 ...
- CentOS关闭防火墙&SELinux
须知: 防火墙配置文件:/etc/sysconfig/iptables 查看防火墙状态:service iptables status 关闭防火墙:service iptables stop 关闭ip ...
- Andrew Ng-ML-第十五章-降维
1.数据压缩 数据压缩不仅能够减小存储空间,并且能够加速学习算法.那么什么是数据压缩呢?下面给出了一个简单的例子: 图1.数据压缩的概念 举了两个例子,一个是横轴x1是厘米,纵轴特征x2是英尺,这明显 ...
- CMFCPropertyGridProperty的使用
设定初始值 CString str(_T("Button")); COleVariant cOlevariant(str); pTypeProperty->SetOrigin ...
- [LeetCode] 458. Poor Pigs_Easy tag: Math
There are 1000 buckets, one and only one of them contains poison, the rest are filled with water. Th ...
- Integer类之缓存
在开始详细的说明问题之前,我们先看一段代码 1 public static void compare1(){ 2 Integer i1 = 127, i2 = 127, i3 = 128, i4 = ...
- FRM-40212: Invalid value for field %s.
Cause: Caused by one of the following: 1. The value is not of the proper data type. 字段类型不对 2 ...
- zw版【转发·台湾nvp系列Delphi例程】HALCON HomMat2dRotate2
zw版[转发·台湾nvp系列Delphi例程]HALCON HomMat2dRotate2 procedure TForm1.Button1Click(Sender: TObject);var op ...
- uva10167
/* 暴力 过了 要使得两半的 樱桃数目相等 去试每一个斜率 还好他这里要的是 A.B 都为正整数 这样范围就锁定在200*100 个点范围内 */ #include <cstdio> # ...
- Description Resource Path LocationType Java compiler level does not match the version of the instal
从别的地方导入进来的maven项目报: Description Resource Path Location TypeJava compiler level does not match the ve ...