用 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数的排名 ...
随机推荐
- 阿里云服务器连接邮箱SMTP服务器time out的解决
给官方提了个工单,回复如下: 去年9月底开始,出于上级对垃圾邮件管控的要求,新购VPC服务器限制了25端口,我们建议您使用邮件服务商的加密465端口. 或者您查询下所希望访问的发信服务是否提供了像阿里 ...
- java之Spring实现控制反转
先来复习一下多态吧,简单点讲,就是一个类的引用可以指向其本身以及其子类的对象. Like these: FatherClass a = new FatherClass(); FatherClass a ...
- 也许CTO并不是终点——没有净土
开篇 不想做将军的士兵不是好士兵,这句话可以有很功利的理解方式,对应到我们自己很可能是:不想做CTO的程序员不是好程序员!几年前对这句话的理解与现在有很多不同,因为我现在已经是一名中小型公司的CTO了 ...
- ArrayList源码分析超详细
ArrayList源码分析超详解 想要分析下源码是件好事,但是如何去进行分析呢?以我的例子来说,我进行源码分析的过程如下几步: 找到类:利用 IDEA 找到所需要分析的类(ztrl+N查找ArraLi ...
- C入门语言基础一[可移植性、涉及的三种文件、编程7个步骤、编译器、链接器]
Review Questions What dose portability mean in the context of programming? 文中讲到的可移植性是什么意思? C本身是不涉及 ...
- (五)SpringBoot2.0基础篇- Mybatis与插件生成代码
SpringBoot与Mybatis合并 一.创建SpringBoot项目,引入相关依赖包: <?xml version="1.0" encoding="UTF-8 ...
- python!!!!惊了,这世上居然还有这么神奇的东西存在
第一次接触到python的时候实在看学习3Blue1Brown的视频线性代数的本质的时候.惊奇的是里面的视频操作,例如向量的变化,线性变换等都是由python用代码打出来的.那时的我只是以为pytho ...
- Bagging与方差
在集成学习中,通常认为Bagging的主要作用是降低方差,而Boosting的主要作用是降低偏差.Boosting能降低偏差很好理解,因为其原理就是将多个弱学习器组合成强学习器.但Bagging为什么 ...
- Java并发之ReentrantLock
一.ReentrantLock简介 ReentrantLock字面意义上理解为可重入锁.那么怎么理解可重入这个概念呢?或者说和我们经常用的synchronized又什么区别呢? ReentrantLo ...
- 2017年的golang、python、php、c++、c、java、Nodejs性能对比[续]
2017年的golang.python.php.c++.c.java.Nodejs性能对比[续] 最近忙,这个话题放了几天,今天来个续集. 上篇传送门: 2017年的golang.python.p ...