可持久化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函数的一部分

  1. if(e[x].pri<e[y].pri) {
  2. int p=++cnt;
  3. e[p]=e[x];
  4. rs(p)=merge(rs(p),y);
  5. pushup(p);
  6. return p;
  7. }
  8. }

那是不是可以写成

  1. if(e[x].pri<e[y].pri) {
  2. int p=++cnt;
  3. e[p]=e[x];
  4. rs(p)=merge(rs(p),y);
  5. pushup(p);
  6. return p;
  7. }

当然是不对的啊,你还要递归呢,cnt当然要变化了

这数组模拟内存浪费的有点多呀,指针应该就没这毛病了,不过我还是学不下去指针233

模板->luoguP3835代码

  1. #include <iostream>
  2. #include <ctime>
  3. #include <cstdlib>
  4. #include <cstdio>
  5. #include <cstring>
  6. #define ls(x) e[x].ls
  7. #define rs(x) e[x].rs
  8. #define FOR(i,a,b) for(int i=a;i<=b;++i)
  9. using namespace std;
  10. const int maxn=500007;
  11. const int inf=0x7fffffff;
  12. int read() {
  13. int x=0,f=1;char s=getchar();
  14. for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
  15. for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
  16. return x*f;
  17. }
  18. struct node {
  19. int ls,rs,size,val,pri;
  20. }e[maxn*50];
  21. int cnt,rt[maxn*50];
  22. void pushup(int x) {
  23. e[x].size=e[ls(x)].size+e[rs(x)].size+1;
  24. }
  25. int make_edge(int x) {
  26. e[++cnt].val=x;
  27. e[cnt].size=1;
  28. e[cnt].pri=rand();
  29. return cnt;
  30. }
  31. int merge(int x,int y) {
  32. if(!x||!y) return x+y;
  33. if(e[x].pri<e[y].pri) {
  34. int p=++cnt;
  35. e[p]=e[x];
  36. rs(p)=merge(rs(p),y);
  37. pushup(p);
  38. return p;
  39. }
  40. else {
  41. int p=++cnt;
  42. e[p]=e[y];
  43. ls(p)=merge(x,ls(p));
  44. pushup(p);
  45. return p;
  46. }
  47. }
  48. void split(int now,int k,int &x,int &y) {
  49. if(!now) x=y=0;
  50. else {
  51. if(e[now].val<=k) {
  52. e[x=++cnt]=e[now];
  53. split(rs(now),k,rs(x),y);
  54. pushup(x);
  55. }
  56. else {
  57. e[y=++cnt]=e[now];
  58. split(ls(now),k,x,ls(y));
  59. pushup(y);
  60. }
  61. }
  62. }
  63. inline int k_th(int now,int k) {
  64. while(233) {
  65. if(k==e[ls(now)].size+1) return now;
  66. if(k<=e[ls(now)].size) now=ls(now);
  67. else k-=e[ls(now)].size+1,now=rs(now);
  68. }
  69. }
  70. int main() {
  71. int n=read(),x,y,z;
  72. FOR(i,1,n) {
  73. int tim=read(),opt=read(),a=read();
  74. rt[i]=rt[tim];
  75. if(opt==1) {
  76. split(rt[i],a,x,y);
  77. rt[i]=merge(merge(x,make_edge(a)),y);
  78. } else if(opt==2) {
  79. split(rt[i],a,x,z);
  80. split(x,a-1,x,y);
  81. y=merge(ls(y),rs(y));
  82. rt[i]=merge(merge(x,y),z);
  83. } else if(opt==3) {
  84. split(rt[i],a-1,x,y);
  85. printf("%d\n",e[x].size+1);
  86. rt[i]=merge(x,y);
  87. } else if(opt==4) {
  88. printf("%d\n",e[k_th(rt[i],a)].val);
  89. } else if(opt==5) {
  90. split(rt[i],a-1,x,y);
  91. if(e[x].size) {
  92. printf("%d\n",e[k_th(x,e[x].size)].val);
  93. rt[i]=merge(x,y);
  94. }
  95. else printf("%d\n",-inf);
  96. } else {
  97. split(rt[i],a,x,y);
  98. if(e[y].size) {
  99. printf("%d\n",e[k_th(y,1)].val);
  100. rt[i]=merge(x,y);
  101. }
  102. else printf("%d\n",inf);
  103. }
  104. }
  105. return 0;
  106. }

可持久化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. 怎样在 Ubuntu 上使用 ZFS 文件系统 | Linux 中国

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/F8qG7f9YD02Pe/article/details/79329762 http://mmbiz ...

  2. inter x86 emulator accelerator(HAXM installer) not compatible with windows

    在SDK manager中遇到如下错误:这将导致AVD后期运行和启动方面的问题. 解决办法: 在如下的网址里面下载haxm-windows_v6_2_0这个文件的压缩包,自己手动安装即可.网站如下:点 ...

  3. 查看crontab的日志记录定位定时任务问题

    1.linux 看 /var/log/cron这个文件就可以,可以用tail -f /var/log/cron观察 2.unix 在 /var/spool/cron/tmp文件中,有croutXXX0 ...

  4. bootstrap modal插件弹出窗口如何限制最大高度,并且在内容过多时可以滚动显示

    .modal-body{ max-height:400px; overflow-y:auto; } 只有在modal-body类上限制高度才能起作用,其他地方的限制均不起作用

  5. Spark SQL初始化和创建DataFrame的几种方式

    一.前述       1.SparkSQL介绍 Hive是Shark的前身,Shark是SparkSQL的前身,SparkSQL产生的根本原因是其完全脱离了Hive的限制. SparkSQL支持查询原 ...

  6. Spark SQL入门用法与原理分析

    Spark SQL是为了让开发人员摆脱自己编写RDD等原生Spark代码而产生的,开发人员只需要写一句SQL语句或者调用API,就能生成(翻译成)对应的SparkJob代码并去执行,开发变得更简洁 注 ...

  7. Spark会把数据都载入到内存么?

    前言 很多初学者其实对Spark的编程模式还是RDD这个概念理解不到位,就会产生一些误解. 比如,很多时候我们常常以为一个文件是会被完整读入到内存,然后做各种变换,这很可能是受两个概念的误导: RDD ...

  8. [py]GIL(全局解释器锁):多线程模式

    在多线程 时同一时刻只允许一个线程来访问CPU,直到解释器遇到I/O操作或者操作次数达到一定数目时才会释放GIL 参考 Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务.多个P ...

  9. 在vue init webpack my-project卡住的问题

    在安装完node.js后,也用cnpm代替了npm,然后使用cnpm在node.js的安装路径下安装了vue-cli:cnpm install --global vue-cli.然后使用vue ini ...

  10. 跟我学Makefile(七)

    定义模式规则 使用模式规则来定义一个隐含规则.一个模式规则就好像一个一般的规则,只是在规则中,目标的定义需要有“%”字符.“%”的意思是表示一个或多个任意字符.在依赖目标中同样可以使用“%”,只是依赖 ...