笛卡尔树
概念
笛卡尔树是一种二叉树, 每一个节点有 \((w, k)\) 两个属性 (在算法竞赛中, \(k\) 通常为数组下标, \(w\) 为权值), 其中 \(w\) 满足堆的性质, \(k\) 满足二叉搜索树的性质.
如果笛卡尔树的 \((k,w)\) 键值确定, 且 \(k\) 互不相同, \(w\) 也互不相同, 那么这棵笛卡尔树的结构是唯一的.
如图是一个小根笛卡尔树.
构建
我们通常利用单调栈来维护右链从而构建起笛卡尔树.
具体地, 考虑将元素按下标顺序一次插入到当前的笛卡尔树中. 那么每次我们插入的元素必然在这棵树的右链的末端. 于是我们可以从下而上地比较当前插入节点的权值与右链节点的权值, 如果找到了一个右链上的节点 \(x\) 满足 \(w_x < w_u\), 那就把 \(u\) 接到 \(x\) 的右儿子上, 而 \(x\) 原本的右子树变成 \(u\) 的左子树.
代码参考
st[++top] = 1;
for (int i = 2; i <= n; ++i) {
while (top and p[st[top]] > p[i])
--top;
if (!top)
ls[i] = st[top + 1];
else
ls[i] = rs[st[top]], rs[st[top]] = i;
st[++top] = i;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现