可持久化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. CSS3实现背景透明,文字不透明

    最近遇到一个需求,要在图片上显示带有半透明背景的文字,效果如下图所示: 看到这个需求之后,第一反应是使用CSS3中的opacity设置元素的透明度. <!DOCTYPE html> < ...

  2. django时间的时区问题

    在用django1.8版本做项目的时候遇到时间的存储与读取不一致的问题,网上找了很多帖子,但都没有讲明白.本文将在项目中遇到的问题及如何解决的尽可能详细的记录下来,当然本文参考了网上大量相关文章. 在 ...

  3. java获取系统当前服务器IP地址

    public String getServiceIp(){ InetAddress address; String myIp; try { address = InetAddress.getLocal ...

  4. 【Python-虫师】自动化测试模型--参数化

    一.自动化测试代码最开始是线性的,后续发展为模块化代码,所以涉及到了函数和方法的引用. 1. 函数和方法的最主要区别: Python的方法中定义函数的时候,函数中必须写self.而单独定义函数的时候则 ...

  5. Java学习之路-Spring的HttpInvoker学习

    Hessian和Burlap都是基于HTTP的,他们都解决了RMI所头疼的防火墙渗透问题.但当传递过来的RPC消息中包含序列化对象时,RMI就完胜Hessian和Burlap了. 因为Hessian和 ...

  6. LINUX的前后台程序查看切换

    1.在Linux终端运行命令的时候,在命令末尾加上 & 符号,就可以让程序在后台运行 root@Ubuntu$ ./tcpserv01 & 2.如果程序正在前台运行,可以使用 Ctrl ...

  7. 查看修改MySQL字符集

    查看修改MySQL字符集 http://blog.sina.com.cn/s/blog_70ac6bec01016fts.html 查看修改MySQL字符集 (2012-08-22 09:53:21) ...

  8. 十天精通CSS3(7)

    :enabled选择器 在Web的表单中,有些表单元素有可用(“:enabled”)和不可用(“:disabled”)状态,比如输入框,密码框,复选框等.在默认情况之下,这些表单元素都处在可用状态.那 ...

  9. 改善深层神经网络_优化算法_mini-batch梯度下降、指数加权平均、动量梯度下降、RMSprop、Adam优化、学习率衰减

    1.mini-batch梯度下降 在前面学习向量化时,知道了可以将训练样本横向堆叠,形成一个输入矩阵和对应的输出矩阵: 当数据量不是太大时,这样做当然会充分利用向量化的优点,一次训练中就可以将所有训练 ...

  10. MatLab 2014a编译jar包时mcc无法使用的问题

    http://blog.csdn.net/heroafei/article/details/43273373 MatLab 2014a编译jar包时mcc无法使用的问题 2015-01-29 16:5 ...