Fhq-Treap.

// Fhq-Treap

const int MAXN = 1e5 + 5;

struct Fhq_Treap {
#define Lson Tr[p].l
#define Rson Tr[p].r struct Fhq_Node {
int l, r, Val, Key, Size;
Fhq_Node () {}
Fhq_Node (int L, int R, int V, int K, int S) {
l = L, r = R, Val = V, Key = K, Size = S;
}
} Tr[MAXN];
int Tot, Root; Fhq_Treap () { Tot = 0, Root = 0; } int Get(int Val) {
Tr[++Tot] = Fhq_Node (0, 0, Val, rand(), 1);
return Tot;
} void Pull (int p) { Tr[p].Size = Tr[Lson].Size + Tr[Rson].Size + 1; } void Split (int p, int Val, int &x, int &y) {
if (!p) {
x = 0, y = 0;
return;
}
if (Tr[p].Val <= Val)
x = p, Split (Rson, Val, Rson, y);
else
y = p, Split (Lson, Val, x, Lson);
Pull (p);
} int Merge (int x, int y) {
if (!x || !y)
return x + y;
if (Tr[x].Key <= Tr[y].Key) {
Tr[x].r = Merge (Tr[x].r, y), Pull (x);
return x;
}
else {
Tr[y].l = Merge (x, Tr[y].l), Pull (y);
return y;
}
} void Insert (int Val) {
int x, y;
Split (Root, Val, x, y), Root = Merge (Merge (x, Get(Val)), y);
} void Delete (int Val) {
int x, y, z;
Split (Root, Val, x, z), Split (x, Val - 1, x, y);
y = Merge (Tr[y].l, Tr[y].r), Root = Merge (Merge (x, y), z);
} int Get_Rank (int Val) {
int x, y, Ret;
Split (Root, Val - 1, x, y);
Ret = Tr[x].Size + 1, Root = Merge (x, y);
return Ret;
} int Get_Val (int Rank) {
int p = Root;
while (p) {
if (Tr[Lson].Size + 1 == Rank)
return Tr[p].Val;
else if (Rank <= Tr[Lson].Size)
p = Lson;
else
Rank -= (Tr[Lson].Size + 1), p = Rson;
}
return 0;
} int Get_Pre (int Val) {
int x, y, p;
Split (Root, Val - 1, x, y), p = x;
while (Rson)
p = Rson;
int ret = Tr[p].Val;
Root = Merge (x, y);
return ret;
} int Get_Next (int Val) {
int x, y, p;
Split (Root, Val, x, y), p = y;
while (Lson)
p = Lson;
int ret = Tr[p].Val;
Root = Merge (x, y);
return ret;
} #undef Lson
#undef Rson
} Tree;

Splay.

struct Splay_Tree {
#define Lson Tr[p].Son[0]
#define Rson Tr[p].Son[1]
#define Inf 0x3f3f3f3f struct Splay_Node {
int Son[2], Val, Cnt, Size, Fa;
Splay_Node () {}
Splay_Node (int V, int C, int S, int F) {
Val = V, Cnt = C, Size = S, Fa = F;
}
} Tr[MAXN]; int Tot, Root; bool Ident (int p) { return Tr[Tr[p].Fa].Son[1] == p; } int Get (int Val, int Fa) {
Tr[++Tot].Fa = Fa, Tr[Tot].Cnt = Tr[Tot].Size = 1, Tr[Tot].Val = Val;
return Tot;
} void Pull (int p) { Tr[p].Size = Tr[Lson].Size + Tr[Rson].Size + Tr[p].Cnt; } void Build () {
Root = Get (-Inf, 0);
Tr[Root].Son[1] = Get (Inf, Root), Pull (Root);
} void Connect (int p, int Fa, int flag) { Tr[Fa].Son[flag] = p, Tr[p].Fa = Fa; } void Rotate (int p) {
int Fa = Tr[p].Fa, Grand = Tr[Fa].Fa;
int Flag1 = Ident (p), Flag2 = Ident (Fa);
Connect (p, Grand, Flag2), Connect (Tr[p].Son[Flag1 ^ 1], Fa, Flag1);
Connect (Fa, p, Flag1 ^ 1), Pull (Fa), Pull (p);
} void Splay (int p, int To) {
for (int Fa = Tr[p].Fa; Tr[p].Fa != To; Rotate (p), Fa = Tr[p].Fa)
if (Tr[Fa].Fa != To)
Ident (p) == Ident (Fa) ? Rotate (Fa) : Rotate (p);
if (!To)
Root = p;
} int Find (int p, int Val) {
if (!p)
return 0;
if (Val == Tr[p].Val)
return p;
else if (Val < Tr[p].Val)
return Find (Lson, Val);
return Find (Rson, Val);
} void Insert (int &p, int Val, int Fa) {
if (!p)
Splay (p = Get (Val, Fa), 0);
else if (Val == Tr[p].Val)
++Tr[p].Cnt, Splay (p, 0);
else if (Val < Tr[p].Val)
Insert (Lson, Val, p);
else
Insert (Rson, Val, p);
} void Delete(int Val) {
int p = Find (Root, Val);
if (!p)
return;
if (Tr[p].Cnt > 1) {
--Tr[p].Cnt, Splay (p, 0), Pull (p);
return;
}
Splay (p, 0);
int l = Lson, r = Rson;
while (Tr[l].Son[1])
l = Tr[l].Son[1];
while (Tr[r].Son[0])
r = Tr[r].Son[0];
Splay (l, 0), Splay (r, l);
Tr[r].Son[0] = 0, Pull (r), Pull (l);
} int Get_Rank (int p, int Val) {
if (!p)
return 0;
if (Val == Tr[p].Val) {
int Res = Tr[Lson].Size + 1; Splay(p, 0);
return Res;
}
else if (Val < Tr[p].Val)
return Get_Rank (Lson, Val);
int Res = Tr[Lson].Size + Tr[p].Cnt;
return Get_Rank (Rson, Val) + Res;
} int Get_Val (int p, int rank) {
if (!p)
return Inf;
if (Tr[Lson].Size >= rank)
return Get_Val (Lson, rank);
else if (Tr[Lson].Size + Tr[p].Cnt >= rank) {
Splay (p, 0);
return Tr[p].Val;
}
return Get_Val (Rson, rank - Tr[Lson].Size - Tr[p].Cnt);
} int Get_Pre(int Val) {
int p = Root, Ret;
while (p) {
if (Tr[p].Val < Val)
Ret = Tr[p].Val, p = Rson;
else
p = Lson;
}
Splay (Root, 0);
return Ret;
} int Get_Next(int Val) {
int p = Root, Ret;
while (p) {
if (Tr[p].Val > Val)
Ret = Tr[p].Val, p = Lson;
else
p = Rson;
}
Splay (Root, 0);
return Ret;
} #undef Lson
#undef Rson
#undef Inf 0x3f3f3f3f
} Tree;

Treap.

// Treap

const int MAXN = 1e5 + 5;

struct Treap_Tree {
#define INF 0x3f3f3f3f
#define mod 998244353
struct Treap_Node {
int son[2], val, dat, cnt, size;
#define lson tr[p].son[0]
#define rson tr[p].son[1]
Treap_Node() {}
Treap_Node(int Val, int Dat, int Cnt, int Size) {
val = Val;
dat = Dat;
cnt = Cnt;
size = Size;
}
} tr[MAXN]; int tot, root; int Get(int val) {
tr[++tot] = Treap_Node(val, rand() % mod, 1, 1);
tr[tot].son[0] = 0;
tr[tot].son[1] = 0;
return tot;
} void Update(int p) { tr[p].size = tr[p].cnt + tr[lson].size + tr[rson].size; } int Get_Rank(int p, int val) {
if (!p)
return 1;
if (val == tr[p].val)
return tr[lson].size + 1;
if (val < tr[p].val)
return Get_Rank(lson, val);
return tr[lson].size + tr[p].cnt + Get_Rank(rson, val);
} int Get_Val(int p, int r) {
if (!p)
return INF;
if (tr[lson].size >= r)
return Get_Val(lson, r);
if (tr[lson].size + tr[p].cnt >= r)
return tr[p].val;
return Get_Val(rson, r - tr[lson].size - tr[p].cnt);
} void Rotate(int &p, int t) {
int q = tr[p].son[!t];
tr[p].son[!t] = tr[q].son[t];
tr[q].son[t] = p;
p = q;
Update(tr[p].son[t]);
Update(p);
} void Insert(int &p, int val) {
if (!p) {
p = Get(val);
return;
}
if (val == tr[p].val) {
tr[p].cnt++;
Update(p);
return;
}
if (val < tr[p].val) {
Insert(lson, val);
if (tr[p].dat < tr[lson].dat)
Rotate(p, 1);
} else {
Insert(rson, val);
if (tr[p].dat < tr[rson].dat)
Rotate(p, 0);
}
Update(p);
} int Get_Pre(int x) {
int p = root, ret = -INF;
while (p) {
if (tr[p].val <= x) {
ret = tr[p].val;
p = rson;
} else
p = lson;
}
return ret;
} int Get_Next(int x) {
int p = root, ret = INF;
while (p) {
if (tr[p].val >= x) {
ret = tr[p].val;
p = lson;
} else
p = rson;
}
return ret;
} void Delete(int &p, int val) {
if (!p)
return;
if (val == tr[p].val) {
if (tr[p].cnt > 1) {
tr[p].cnt--;
Update(p);
return;
}
if (lson || rson) {
if (rson == 0 || tr[lson].dat > tr[rson].dat) {
Rotate(p, 1);
Delete(rson, val);
} else {
Rotate(p, 0);
Delete(lson, val);
}
Update(p);
} else
p = 0;
return;
}
if (val < tr[p].val)
Delete(lson, val);
else
Delete(rson, val);
Update(p);
}
#undef lson
#undef rson
} tree;

Template -「平衡树」的更多相关文章

  1. 「luogu3380」【模板】二逼平衡树(树套树)

    「luogu3380」[模板]二逼平衡树(树套树) 传送门 我写的树套树--线段树套平衡树. 线段树上的每一个节点都是一棵 \(\text{FHQ Treap}\) ,然后我们就可以根据平衡树的基本操 ...

  2. Template -「整体二分」

    写的简单.主要是留给自己做复习资料. 「BZOJ1901」Dynamic Rankings. 给定一个含有 \(n\) 个数的序列 \(a_1,a_2 \dots a_n\),需要支持两种操作: Q ...

  3. 「SCOI2014」方伯伯的 OJ 解题报告

    「SCOI2014」方伯伯的 OJ 和列队有点像,平衡树点分裂维护即可 但是需要额外用个set之类的对编号查找点的位置 插入完了后记得splay,删除时注意特判好多东西 Code: #include ...

  4. LOJ 3184: 「CEOI2018」斐波那契表示法

    题目传送门:LOJ #3184. 题意简述: 题目说得很清楚了. 题解: 首先需要了解「斐波那契数系」为何物. 按照题目中定义的斐波那契数列 \(F_n\),可以证明,每个非负整数 \(n\) 都能够 ...

  5. 「JSOI2011」任务调度

    「JSOI2011」任务调度 传送门 一开始还在想写平衡树,看到 \(\text{TRANS}\) 操作后就晓得要用可并堆了. 这题好像就是个可并堆的板子题??? ADD 直接往对应的对里面加元素 D ...

  6. 「NOI2005」维护数列

    「NOI2005」维护数列 传送门 维护过程有点像线段树. 但我们知道线段树的节点并不是实际节点,而平衡树的节点是实际节点. 所以在向上合并信息时要加入根节点信息. 然后节点再删除后编号要回退(栈), ...

  7. 「HNOI2004」宠物收养场

    「HNOI2004」宠物收养场 传送门 对宠物和人各维护一棵平衡树,每次 \(\text{split}\) 的时候记得判一下子树是否为空,然后模拟就好了. 参考代码: #include <alg ...

  8. 「TJOI2013」最长上升子序列

    「TJOI2013」最长上升子序列 传送门 这个 \(\text{DP}\) 应该都会撒: \[dp_i = \max_{j < i,a_j < a_i}\left\{dp_j\right ...

  9. 「C++」理解智能指针

    维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...

随机推荐

  1. c/c++递归打印文件夹

    调用linux的系统函数,实现tree的功能,递归打印文件夹 使用到得函数: DIR *opendir(const char *name); // 打开文件夹 struct dirent *readd ...

  2. 干货|带你体验一次原生OpenStack云平台发放云主机的过程

    一个执着于技术的公众号 1 前言 上一章节我们完成了OpenStack云平台的搭建工作,今天就带大家一起学习下如何发放一台云主机 点击查看:如何搭建一套OpenStack云平台 2 发放OpenSta ...

  3. Fuzzing101系列 Exercise 1 - Xpdf

    序言 Fuzzing101系列包含针对10 个真实目标的10个练习,在练习中一步一步学习Fuzzing技术的知识. 模糊测试(Fuzzing/Fuzz)是一种自动化软件测试技术,它基于为程序提供随机或 ...

  4. 中国电子云数据库 Mesh 项目 DBPack 的实践

    作者:刘晓敏 2022 年 4 月,中国电子云开源了其云原生数据库 Mesh 项目 DBPack.该项目的诞生,旨在解决用户上云过程中面临的一些技术难点,诸如分布式事务.分库分表等.由于它数据库 Me ...

  5. 拯救一切强迫症 - 读《编写可维护的 JavaScript》(一)

    拯救一切强迫症 - 读<编写可维护的 JavaScript>(一) 本文写于 2020 年 4 月 24 日 我在小学的时候就有接触过编程,所以读大一的时候 C 语言还算是轻车熟路.自然会 ...

  6. KeyDB重量发布6.3.0开源版

    摘要:5月12日 KeyDB 社区隆重发布了 6.3.0开源版本,将与华为加拿大研究院DCS团队2021-2022年合作的成果,深度优化的企业版的能力贡献给了开源社区. KeyDB是目前Redis 分 ...

  7. 渗透:Nmap

    Nmap,也就是Network Mapper,最早是Linux下的网络扫描和嗅探工具包. nmap是一个网络连接端扫描软件,用来扫描网上电脑开放的网络连接端.确定哪些服务运行在哪些连接端,并且推断计算 ...

  8. 设计并实现加法器类 Adder

    学习内容:设计并实现加法器类 Adder 代码示例: package 实验三; import java.util.Scanner; public class Adder { private int n ...

  9. Git技法:.gitignore、移除暂存与撤销修改

    1. .gitignore常见项目添加 1.1 .gitignore模板 .gitignore针对每个语言都有对应的模板,在GitHub创建项目时就可以选择(你可以在GitHub提供的.gitigno ...

  10. 【freertos】010-消息队列概念及其实现细节

    目录 前言 10.1 消息队列概念 10.2 消息队列的数据传输机制 10.3 消息队列的阻塞访问机制 10.4 消息队列使用场景 10.5 消息队列控制块 10.5.1 队列控制块源码 10.5.2 ...