用 fhq_Treap 实现可持久化平衡树
支持对历史版本进行操作的平衡树
Treap 和 Splay 都是旋来旋去的
这样平衡树可持久化听起来不太好搞?
还有 fhq_Treap !
每次涉及操作就复制一个节点出来
操作历史版本就继承它的根继续往下搞
在 Split 和 Merge 里加上有关可持久化的操作即可
这里因为写了根据权值来分割的 Split
所以就写比较传统的 getrank 了 = =
所以其他的一些涉及 Split 的操作都改了改
其实还是挺好写的
终于还是写了传引用的 Split
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cstdio>
#include<cmath>
#include<ctime>
#define lson t[cur].ch[0]
#define rson t[cur].ch[1]
using namespace std; const int MAXN = 500001, inf = 0x7fffffff; struct Node{
int ch[2], siz, val, prio;
Node(){ch[0] = ch[1] = siz = val = 0;}
}t[MAXN * 50];
int Root[MAXN], n, poolcur; inline int rd() {
register int x = 0;
register char c = getchar();
register bool f = false;
while(!isdigit(c)) {
if(c == '-') f = true;
c = getchar();
}
while(isdigit(c)) {
x = x * 10 + c - 48;
c = getchar();
}
return f ? -x : x;
}
inline int newnode(int val) {
register int cur = ++poolcur;
t[cur].siz = 1;
t[cur].prio = rand();
t[cur].val = val;
return cur;
}
inline void pushup(int cur) {
t[cur].siz = t[lson].siz + t[rson].siz + 1;
return;
}
void Split(int cur, int val, int &x, int &y) {
if(!cur) x = y = 0;
else {
if(t[cur].val <= val) {
x = ++poolcur; t[x] = t[cur];
Split(t[x].ch[1], val, t[x].ch[1], y);
pushup(x);
} else {
y = ++poolcur; t[y] = t[cur];
Split(t[y].ch[0], val, x, t[y].ch[0]);
pushup(y);
}
}
return;
}
int Merge(int x, int y) {
if(!x) return y; if(!y) return x;
if(t[x].prio < t[y].prio) {
int nw = ++poolcur; t[nw] = t[x];
t[x].ch[1] = Merge(t[x].ch[1], y);
pushup(x);
return x;
} else {
int nw = ++poolcur; t[nw] = t[y];
t[y].ch[0] = Merge(x, t[y].ch[0]);
pushup(y);
return y;
}
}
void Insert(int &root, int val) {
int x, y;
Split(root, val, x, y);
root = Merge(Merge(x, newnode(val)), y);
return;
}
void Remove(int &root, int val) {
int x, y, z;
Split(root, val, x, z);
Split(x, val - 1, x, y);
y = Merge(t[y].ch[0], t[y].ch[1]);
root = Merge(Merge(x, y), z);
return;
}
int getrnk(int &root, int val) {
int x, y;
Split(root, val - 1, x, y);
int ans = t[x].siz + 1;
root = Merge(x, y);
return ans;
}
int findkth(int cur, int k) {
if(k <= t[lson].siz) return findkth(lson, k);
if(k == t[lson].siz + 1) return t[cur].val;
return findkth(rson, k - t[lson].siz - 1);
}
int getpre(int &root, int val) {
int x, y;
Split(root, val - 1, x, y);
if(!x) return -inf;
int k = t[x].siz;
int ans = findkth(x, k);
root = Merge(x, y);
return ans;
}
int getnxt(int &root, int val) {
int x, y;
Split(root, val, x, y);
if(!y) return inf;
int ans = findkth(y, 1);
root = Merge(x, y);
return ans;
} int main() {
srand(time(NULL));
n = rd();
int ver, opt, x;
for(int i = 1; i <= n; ++i) {
ver = rd(); opt = rd(); x = rd();
Root[i] = Root[ver];
switch(opt) {
case 1: Insert(Root[i], x); break;
case 2: Remove(Root[i], x); break;
case 3: printf("%d\n", getrnk(Root[i], x)); break;
case 4: printf("%d\n", findkth(Root[i], x)); break;
case 5: printf("%d\n", getpre(Root[i], x)); break;
case 6: printf("%d\n", getnxt(Root[i], x)); break;
}
}
return 0;
}
用 fhq_Treap 实现可持久化平衡树的更多相关文章
- [Luogu 3835]【模板】可持久化平衡树
Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本): 插入x数 删除x数(若有多个相同的数,因只删除一个,如果没有请忽略该操作 ...
- Luogu P3835 【模板】可持久化平衡树(fhq Treap)
P3835 [模板]可持久化平衡树 题意 题目背景 本题为题目普通平衡树的可持久化加强版. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本 ...
- 2021.07.02 P1383 高级打字机题解(可持久化平衡树)
2021.07.02 P1383 高级打字机题解(可持久化平衡树) 分析: 从可以不断撤销并且查询不算撤销这一骚操作可以肯定这是要咱建一棵可持久化的树(我也只会建可持久化的树,当然,还有可持久化并查集 ...
- 可持久化Trie & 可持久化平衡树 专题练习
[xsy1629]可持久化序列 - 可持久化平衡树 http://www.cnblogs.com/Sdchr/p/6258827.html [bzoj4260]REBXOR - Trie 事实上只是一 ...
- 洛谷P3835 【模板】可持久化平衡树
题目背景 本题为题目 普通平衡树 的可持久化加强版. 数据已经经过强化 感谢@Kelin 提供的一组hack数据 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作( ...
- P3835 【模板】可持久化平衡树
题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本): 插入x数 删除x数(若有多个相同的数,因只删除一个,如果没有请忽略该操作) 查询x数的 ...
- 【LG3835】可持久化平衡树
[LG3835]可持久化平衡树 题面 洛谷 解法一 参考文章 rope大法好 \(rope\)基本操作: #include<ext/rope> using namespace __gnu_ ...
- [cogs2314][HZOI 2015] Persistable Editor - 可持久化平衡树
[cogs2314][HZOI 2015]Persistable Editor - 可持久化平衡树 题目链接 首先吐槽扯淡几句 [题目描述] 维护一种可持久化的文本编辑器,支持下列操作: 1 p st ...
- LG3835 【模板】可持久化平衡树
题意 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本): 插入x数 删除x数(若有多个相同的数,因只删除一个,如果没有请忽略该操作) 查询x数的排名 ...
随机推荐
- Ubuntu16.04部署phantomjs的一个问题
首先phantomjs是作为pyspider的一个外部依赖组件部署的. apt安装完出现问题: QXcbConnection: Could not connect to display Phantom ...
- 阿里云服务器连接邮箱SMTP服务器time out的解决
给官方提了个工单,回复如下: 去年9月底开始,出于上级对垃圾邮件管控的要求,新购VPC服务器限制了25端口,我们建议您使用邮件服务商的加密465端口. 或者您查询下所希望访问的发信服务是否提供了像阿里 ...
- linux下安装apc
wget htdtp://pecl.php.net/get/APC tar zxvf APC-3.1.3p.tgz cd APC-3.1.3p /usr/local/php/bin/phpize ./ ...
- SQL基本语句的优化10个原则
原则一:尽量避免在列上进行运算,这样会导致索引失效. 例如: ; 优化: SELECT * FROM table WHERE d >= '2011-01-01'; 原则二:使用JOIN时,应该用 ...
- C++神奇算法库——#include<algorithm>
算法(Algorithm)为一个计算的具体步骤,常用于计算.数据处理和自动推理.C++ 算法库(Algorithms library)为 C++ 程序提供了大量可以用来对容器及其它序列进行算法操作的函 ...
- python中的类
以下内容是python tutorial的读书笔记: 一.命名空间的分层 二.local赋值语句,nonlocal和global的区别 local赋值语句,它是无法实现对于最里层的作用域的重新绑定的 ...
- VueJs(11)---vue-router(进阶2)
vue-router(进阶2) 上篇文章讲了第一篇vue-router相关文章,文章地址:VueJs(10)---vue-router(进阶1) 一.命名路由 有时候,通过一个名称来标识一个路由显得更 ...
- Angular路由——路由守卫
一.路由守卫 当用户满足一定条件才被允许进入或者离开一个路由. 路由守卫场景: 只有当用户登录并拥有某些权限的时候才能进入某些路由. 一个由多个表单组成的向导,例如注册流程,用户只有在当前路由的组件中 ...
- flume原理
1. flume简介 flume 作为 cloudera 开发的实时日志收集系统,受到了业界的认可与广泛应用.Flume 初始的发行版本目前被统称为 Flume OG(original generat ...
- Python学习 Part5:输入输出
Python学习 Part5:输入输出 1. 格式化输出 三种输出值的方法: 表达式语句 print()函数 使用文件对象的write()方法 两种方式格式化输出: 由自己处理整个字符串,通过使用字符 ...