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. input 相关

    1.label 标签 for 属性同 input 标签 id 属性联系之一

  2. ngx-lua实现高级限流方式一

    基于POST请求体中的某个参数限流 背景 电商平台有活动,活动涉及优惠券的抢券,优惠券系统对大并发支持略差,为了保护整体系统平稳,因此在入口Nginx层对抢券接口做了一层限流. 完整实现如下: lua ...

  3. IPC机制与线程的操作

    目录 Queue模块 IPC机制(进程间通信) 生产者消费者模型 线程理论 创建线程的两种方式 线程实现TCP服务端的并发 线程join方法 线程数据共享 线程对象属性和方法 守护线程 GIL全局解释 ...

  4. 羿网通WT2100网络测试仪端口开关功能应用案例

    端口开关是羿网通WT2100具备的一项全局性的功能,使用客户端软件Packlark连接WT2100后无需进入具体功能即可使用.该功能是通过控制设备上的以太网开关实现快速.便捷地切换网口通断状态的目标, ...

  5. 渗透测试之sql注入验证安全与攻击性能

    由于渗透测试牵涉到安全性以及攻击性,为了便于交流分享,本人这里不进行具体网址的透露了. 我们可以在网上查找一些公司官方网站如(http://www.XXXXXX.com/xxxx?id=1) 1.拿到 ...

  6. SCI论文写作注意事项

    1. 先写结论:(划定范围,以防添加无效的内容)     并非一开始就把整个结论都写出来,而是把

  7. 更换conda镜像源、pip镜像源

    镜像源一般有两点特别需要注意,一个是Conda源,一个是Pip源: 更换Conda源,以更换清华Conda源为例: Anaconda 镜像使用帮助 Anaconda 是一个用于科学计算的 Python ...

  8. 2021.03.06【NOIP提高B组】模拟 总结

    T1 看起来十分复杂,打表后发现答案是 \(n*m\mod p\) 具体的证明... 原式的物理意义,就是从坐标原点(0,0),用每一种合法的斜率, 穿过坐标[1 ~ n , 1 ~ m]的方阵中的整 ...

  9. 2020.10.17【普及组】模拟赛C组 总结

    总结 这次比赛 120 分,老师说上 200 是不容易的,但我觉得这不是我真的水平 改题情况 T1 题目大意:有 N 个小朋友,每个小朋友有 \(B_i\) 个朋友,问从中随机选 3 人使得 3 人关 ...

  10. C# 将XML转为PDF

    XML,即可扩展标记语言文,件是一种标准的文本文件,它使用特定的标记来描述文档的结构以及其他特性.通过将 XML 文档转换为 PDF格式,能够满足更多程序.设备对文件预览.读取或展示的需要,也更便于文 ...