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. mybaitis查询 (数据库与实体类字段名不相同)

    1.这是我的数据库字段名和实体类字段名 2.方法 方法一: 查询的结果标题 会跟实体类的属性一一匹配,一定要一致就算数据库字段和属性不一致,我们可以把查询结果设置一个别名,让别名=属性名 方法二:使用 ...

  2. css的flex布局调试

    学习经验-css的flex布局 今天遇到一个小问题 在给三个div布局时,设置父元素display:flex 此时三个div的宽度均为50%,他们并没有超出屏幕的宽度,还是撑满了父元素. 为什么呢? ...

  3. TCP 协议有哪些缺陷?

    作者:小林coding 图解计算机基础网站:https://xiaolincoding.com 大家好,我是小林. 忽然思考一个问题,TCP 通过序列号.确认应答.超时重传.流量控制.拥塞控制等方式实 ...

  4. 使用VPLS跨地域多站点建立二层交换网络

    VLL解决方案 https://www.cnblogs.com/darkchen/p/14652540.html 接上篇文档引出VPLS VLL可以跨地域建立二层交换网络,但有个缺陷是只支持两个sit ...

  5. arts-week14

    Algorithm 923. 3Sum With Multiplicity - LeetCode Review Building a network attached storage device w ...

  6. 好客租房25-react中的事件处理(事件对象)

    3.2事件对象 可以通过事件处理程序的参数 React中的事件对象叫做:合成事件(对象) 合成事件:兼容所有浏览器 //导入react     import React from 'react'   ...

  7. [漏洞复现] [Vulhub靶机] Struts2-045 Remote Code Execution Vulnerablity(CVE-2017-5638)

    免责声明:本文仅供学习研究,严禁从事非法活动,任何后果由使用者本人负责. 0x00 背景知识 Apache Struts 2是美国Apache软件基金会的一个开源项目,是一套用于创建企业级Java W ...

  8. antdVue问题

    antdVue框架问题 #(1)slot/slot-scope插槽问题 一般用于表格数据渲染 eg: <span slot="user" slot-scope="t ...

  9. 免申请直接用上 IDEA 新 UI,只需要这三步配置

    早上给大家介绍了IDEA官方宣布正在开发一套全新的UI,但目前是预览版需要申请才能体验. 随后马上就有网友分享了,不需要申请直接就能激活体验的方法. 本期视频:https://www.bilibili ...

  10. JAVA - 序列化的方式

    JAVA - 序列化的方式 序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读 ...