可持久化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学习笔记的更多相关文章

  1. fhq treap 学习笔记

    序 今天心血来潮,来学习一下fhq treap(其实原因是本校有个OIer名叫fh,当然不是我) 简介 fhq treap 学名好像是"非旋转式treap及可持久化"...听上去怪 ...

  2. FHQ treap学习(复习)笔记

    .....好吧....最后一篇学习笔记的flag它倒了..... 好吧,这篇笔记也鸽了好久好久了... 比赛前刷模板,才想着还是补个坑吧... FHQ,这个神仙(范浩强大佬),发明了这个神仙的数据结构 ...

  3. 左偏树 / 非旋转treap学习笔记

    背景 非旋转treap真的好久没有用过了... 左偏树由于之前学的时候没有写学习笔记, 学得也并不牢固. 所以打算写这么一篇学习笔记, 讲讲左偏树和非旋转treap. 左偏树 定义 左偏树(Lefti ...

  4. treap学习笔记

    treap是个很神奇的数据结构. 给你一个问题,你可以解决它吗? 这个问题需要treap这个数据结构. 众所周知,二叉查找树的查找效率低的原因是不平衡,而我们又不希望用各种奇奇怪怪的旋转来使它平衡,那 ...

  5. fhq treap抄袭笔记

    目录 碎碎念 点一下 注意!!! 模板 fhq treap 碎碎念 我咋感觉合并这么像左偏树呢 ps:难道你们的treap都是小头堆的吗 fhq真的是神人 现在看以前学的splay是有点恶心,尤其是压 ...

  6. Treap + 无旋转Treap 学习笔记

    普通的Treap模板 今天自己实现成功 /* * @Author: chenkexing * @Date: 2019-08-02 20:30:39 * @Last Modified by: chenk ...

  7. [Treap][学习笔记]

    平衡树 平衡树就是一种可以在log的时间复杂度内完成数据的插入,删除,查找第k大,查询排名,查询前驱后继以及其他许多操作的数据结构. Treap treap是一种比较好写,常数比较小,可以实现平衡树基 ...

  8. Treap-平衡树学习笔记

    平衡树-Treap学习笔记 最近刚学了Treap 发现这种数据结构真的是--妙啊妙啊~~ 咳咳.... 所以发一发博客,也是为了加深蒟蒻自己的理解 顺便帮助一下各位小伙伴们 切入正题 Treap的结构 ...

  9. 「学习笔记」 FHQ Treap

    FHQ Treap FHQ Treap (%%%发明者范浩强年年NOI金牌)是一种神奇的数据结构,也叫非旋Treap,它不像Treap zig zag搞不清楚(所以叫非旋嘛),也不像Splay完全看不 ...

  10. 「FHQ Treap」学习笔记

    话说天下大事,就像fhq treap —— 分久必合,合久必分 简单讲一讲.非旋treap主要依靠分裂和合并来实现操作.(递归,不维护fa不维护cnt) 合并的前提是两棵树的权值满足一边的最大的比另一 ...

随机推荐

  1. Maven中的pom.xml配置文件详解

    原文:http://blog.csdn.net/u012152619/article/details/51485297 <project xmlns="http://maven.apa ...

  2. Django - 用户认证、用户组、用户权限

    https://www.cnblogs.com/ccorz/p/6358074.html auth模块是Django提供的标准权限管理系统,可以提供用户身份认证, 用户组和权限管理. auth可以和a ...

  3. Wireless Network--poj2236(并查集)

    Description An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated Medical team) have ...

  4. vmware 安装 kali linux 系统到U盘 启动错误(initramfs:) 修复方法

    安装kalilinux到U盘 启动之后出现这个错误: 这是grub路径不对. 解决办法: 在这模式下可以输入命令:blkid 查看所列举出的磁盘 找到你的U盘系统 TYPE="ext4&qu ...

  5. Jquery-plugins-toastr-消息提示

    toastr是一个基于jQuery简单.漂亮的消息提示插件,使用简单.方便,可以根据设置的超时时间自动消失. 1.使用很简单,首选引入toastr的js.css文件 html <link rel ...

  6. cube-ui的用法

    .安装:npm install cube-ui -S .修改 .babelrc:(添加到plugins中去) { "plugins": [ ["transform-mod ...

  7. ubuntu设置目录容量大小

    1:方法如下 sudo dd if=/dev/zero of=/root/disk1.img bs=2M count=10      //          2M*10=20M    zero 是de ...

  8. [py][mx]django使用class写views-免去判断方法的烦恼

    修改views使用class模式 类模式写views - 免去了函数模式的判断的烦恼 users/views.py from django.views.generic import View clas ...

  9. 性能测试之nmon对linux服务器的监控

    大家都知道在做性能测试的时候,需要监控服务器的资源情况,而大多数服务器是Linux系统,网上资料嘿多,这里汇总介绍下Nmon监控工具: -------------------------------- ...

  10. dp训练

    根据这位大佬的https://www.cnblogs.com/Bunnycxk/p/7360183.html 题目链接:https://www.luogu.org/problemnew/show/P3 ...