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. 分享一款高逼格的Linux磁盘信息查看工具

    关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 可以使用df命令来显示在Linux.macOS和类Unix系统中挂载的文件系统上有多少可用磁盘 ...

  2. Linux 运维工程师面试问答录(推荐阅读)

    一个执着于技术的公众号 本文整理了一些比较常见的 Linux 相关的面试题目,该问答录主要分为基础知识篇和服务器篇.内容主要涉及 Linux 基本原理.常用命令操作.服务器应用等部分的内容. Linu ...

  3. Linux系统常用命令速查手册

    点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 系统信息 arch      #显示机器的处理器架构(1 ...

  4. 【面试普通人VS高手系列】说一说Mybatis里面的缓存机制

    一个工作了 5年的程序员,在私信里面不断向我诉苦. 他说,他用了Mybatis这么久,怎么滴也算是精通Mybatis了吧. 结果竟然在Mybatis这个面试题上翻车了! 真的好烦! 好吧,我们今天来看 ...

  5. Oracle19c单实例数据库配置OGG单用户数据同步测试

    目录 19c单实例配置GoldenGate 并进行用户数据同步测试 一.数据库操作 1.开启数据库附加日志 2.开启数据库归档模式 3.开启goldengate同步 4.创建goldengate管理用 ...

  6. 虚拟机中CentOS-7.9的硬盘空间扩容(EXSI)

    目录 一.增加虚机容量 二.创建新的分区 三.格式化新分区 四.lvm实现卷扩容 五.文件系统的扩容 大家好,我是LSF,发现一台虚机上 /dev/mapper/centos-root Use%已经快 ...

  7. iOS全埋点解决方案-时间相关

    前言 ​ 我们使用"事件模型( Event 模型)"来描述用户的各种行为,事件模型包括事件( Event )和用户( User )两个核心实体.我们在描述用户行为时,往往只需要描述 ...

  8. 零基础学Java第一节(语法格式、数据类型)

    本篇文章是<零基础学Java>专栏的第一篇文章,从本篇文章开始,将会连更本专栏,带领大家将Java基础知识彻底学懂,文章采用通俗易懂的文字.图示及代码实战,从零基础开始带大家走上高薪之路! ...

  9. netty系列之:netty对marshalling的支持

    目录 简介 netty中的marshalling provider Marshalling编码器 Marshalling编码的另外一种实现 总结 简介 在之前的文章中我们讲过了,jboss marsh ...

  10. 151-模型-Power BI&Power Pivot模型DAX函数使用量分析

    151-模型-Power BI&Power Pivot模型DAX函数使用量分析 1.背景 我们在 Power BI 或者 Power Pivot 项目中会写很多的 DAX 表达式.在最后项目交 ...