当前位置: 首页 > news >正文

浅学 FHQ

初学者千万不要被吓到,不要因为代码略长就害怕,打的代码越来越长才能增长码力。

以 模板题 为例。

维护信息

  1. key,也就是维护的序列或其他东西里的值。
  2. val,Treap 带的用于平衡时间复杂度的随机参数。
  3. l,r,左右儿子。
  4. siz,节点的子树大小。

主要操作

合并

合并两颗合法的 Treap,且其中一颗里的 key 值全部大于另外一颗。

令前者的根为 \(y\),后者的根为 \(x\)。比较两者的 val,大的一方作为父亲,小的一方作为儿子,以维持平衡,注意以 \(x\) 为根的树一定在左,所以 \(y\) 只能做右儿子,\(x\) 只能做左儿子。

假设以 \(x\) 为根,那么更新 \(x\) 的右儿子,再将 \(x\) 的右儿子和 \(y\) 合并即可,递归处理。\(y\) 同理。

分裂

以一个值 \(k\) 为界,小于等于 \(k\) 的放到一棵树里,大于 \(k\) 的放到一颗树里。

同样在递归过程中处理。比较当前的根节点 key\(k\),如果 key \(\le k\),那么左子树和根节点都应被切到左边,递归处理右子树。反之同理。稍微复杂的细节建议看代码。

更新

分裂合并后树的形态都会改变,所以要及时 pushup,更新子树大小。

完成询问操作

插入

以插入值为界,分裂当前的平衡树,再按顺序合并左边,新建的节点,右边。

删除

先分裂成小于等于删除值的和大于的,再将前者以删除值 \(-1\) 为界分裂成小于和等于的。

如何删除等于的这颗树里的一个?只需要把这颗树的根的左右儿子合并即可,根自然就被删除了,然后把这三棵树重新按顺序合并即可。

查询排名

将树分裂成小于等于查询值 \(-1\) 的和大于查询值的,输出左边子树大小 \(+1\),重新合并。

查询第 \(k\)

若左子树 siz \(\ge k\),递归左边,若左子树 siz \(+1\) 等于 \(k\),返回根节点 key,否则递归右子树。

查询前驱

将大于等于查询值的放到右边(就是前面的按查询值 \(-1\) 为界),然后用查询第 \(k\) 查询左子树里的最后一个(第 siz 个)。重新合并。

查询后继

同理,将小于等于查询值的放到左边,查询右子树的第一个。重新合并。


FHQ 充分发扬人类智慧,用两个基础操作实现了平衡树,也很好理解,强烈推荐大家学习。

最后看看板子题代码。

#include <bits/stdc++.h>
// #define int long long
#define x first
#define y second
using namespace std;
typedef pair <int, int> pii;
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-10, PI = acos (-1);
const int N = 2e5 + 10, M = 2e5 + 10;
//const int mod = 1e9 + 7;
//const int mod = 998244353;int idx, root;
struct node
{int val, key;int l, r, siz;
} tr[N];int get_node(int x)
{tr[++idx] = {rand (), x, 0, 0, 1};return idx;
}void pushup(int u)
{tr[u].siz = tr[tr[u].l].siz + tr[tr[u].r].siz + 1;
}void split(int p, int &l, int &r, int k)//l,r 记录分裂后的根
{if (!p) //空节点返回{l = r = 0;return;}if (tr[p].key <= k) //把左子树扔到左边,处理右子树{l = p;split (tr[p].r, tr[p].r, r, k);//要将根节点的右儿子处理为右儿子分裂出来的左边}else{r = p;split (tr[p].l, l, tr[p].l, k);//同理}pushup (p);//更新
}int merge(int x, int y)
{if (!x || !y) return x | y;//有一个为空直接返回另一个if (tr[x].val > tr[y].val)//x 为根{tr[x].r = merge (tr[x].r, y);pushup (x);return x;}else//y 为根{tr[y].l = merge (x, tr[y].l);pushup (y);return y;}
}void insert(int x)
{int l, r;split (root, l, r, x);root = merge (merge (l, get_node (x)), r);
}void del(int x)
{int tep, bg, sm, eq;//bg:>, sm:<, eq:=.split (root, tep, bg, x);split (tep, sm, eq, x - 1);eq = merge (tr[eq].l, tr[eq].r);root = merge (merge (sm, eq), bg);
}int get_rank(int x)
{int l, r;split (root, l, r, x - 1);int ans = tr[l].siz + 1;root = merge (l, r);return ans;
}int get_kth(int p, int k)
{if (tr[tr[p].l].siz >= k) return get_kth (tr[p].l, k);else if (tr[tr[p].l].siz + 1 == k) return tr[p].key;else return get_kth (tr[p].r, k - tr[tr[p].l].siz - 1);
}int get_prev(int x)
{int l, r;split (root, l, r, x - 1);int ans = get_kth (l, tr[l].siz);root = merge (l, r);return ans;
}int get_next(int x)
{int l, r;split (root, l, r, x);int ans = get_kth (r, 1);root = merge (l, r);return ans;
}int main()
{// srand (time (0));int n;cin >> n;while (n--){int op, x;cin >> op >> x;if (op == 1) insert (x);if (op == 2) del (x);if (op == 3) cout << get_rank (x) << "\n";if (op == 4) cout << get_kth (root, x) << "\n";if (op == 5) cout << get_prev (x) << "\n";if (op == 6) cout << get_next (x) << "\n";}return 0;
}

完结撒花 ★,°:.☆( ̄▽ ̄)/$:.°★ 。

http://www.sczhlp.com/news/10228/

相关文章:

  • DeepCompare文件深度对比软件:智能文本对比与差异统计功能完全指南
  • 单据上采购数量按3个单位分别显示数量
  • 致敬2025年还在写博客的你
  • MyBatis-Plus
  • 概率论的基础
  • 【IEEE出版】第三届电力、电网和储能国际学术会议(PGES 2025)
  • 记录下MySQL的分区表
  • 从 “JSON 字段适配噩梦” 到 “Spring Boot 优雅解决方案”,你只差这一篇
  • 【IEEE出版】第四届电力系统与电力工程国际学术会议(PSPE 2025)
  • 题解:P10299 [CCC 2024 S5] Chocolate Bar Partition
  • 关闭Ollama开机启动项
  • MySQL 根据一个表的字段值,更新另一个表的字段
  • DeepCompare文件深度对比软件:智能同步滚动与对比视图管理功能完全指南
  • 书单
  • 2025 款潘通色卡 PS/AI 插件推荐:解锁高效配色新体验
  • Dubbo源码—1.服务发布的主要流程
  • 剑指offer-20、包含min函数的栈
  • QueryCon 2019:osquery的重大转折点 - 技术治理与社区共建
  • 基于Transformer的百万级文本分类技术
  • 详细介绍:网络基础1-11综合实验(eNSP):vlan/DHCP/Web/HTTP/动态PAT/静态NAT
  • Omnissa Horizon Windows OS Optimization Tool 2506 - Windows 系统映像优化工具
  • docker 容器化部署 vLLM 启动大模型
  • App Linking 助力应用场景创新,操作步骤立省 60%
  • ChatGpt 5系列文章1——编码与智能体
  • Cisco Catalyst 9800-CL IOS XE 17.18.1 发布,新增功能简介
  • Cisco Modeling Labs (CML) 2.9.0 - 网络仿真工具
  • Omnissa App Volumes 4, version 2506 - 实时应用程序交付系统
  • Omnissa Dynamic Environment Manager 2506 - 个性化动态 Windows 桌面环境管理
  • AES 加密模式演进:从 ECB、CBC 到 GCM 的 C# 深度实践
  • Cisco Catalyst 9800 WLC IOS XE 17.18.1 发布,新增功能简介