笛卡尔树通过结合二叉搜索树和堆性质,将RMQ问题转化为LCA问题,利用单调栈在O(n)时间内构建,并配合DFS与稀疏表实现O(1)查询,适用于静态数据的高效区间最值查询。

笛卡尔树(Cartesian Tree)是一种结合了二叉搜索树和堆性质的数据结构,常用于解决RMQ(Range Minimum/Maximum Query,区间最值查询)问题。通过将RMQ转化为LCA(Lowest Common Ancestor,最近公共祖先)问题,笛卡尔树能在线性预处理后实现O(1)查询,是C++中高效处理静态RMQ的重要手段。
笛卡尔树满足两个关键性质:
构建完成后,原数组任意区间的最小值对应笛卡尔树中该区间对应节点的LCA。这使得RMQ问题可通过LCA求解。
利用单调栈可以在O(n)时间内完成构建。核心思路是维护一个值递增的栈,逐个插入元素并调整树结构。
立即学习“C++免费学习笔记(深入)”;
示例代码:
#include <vector>
#include <stack>
using namespace std;
<p>struct Node {
int val, idx;
Node<em> left, </em> right;
Node(int v, int i) : val(v), idx(i), left(nullptr), right(nullptr) {}
};</p><p>Node* buildCartesianTree(const vector<int>& arr) {
int n = arr.size();
if (n == 0) return nullptr;</p><pre class='brush:php;toolbar:false;'>vector<Node*> nodes;
for (int i = 0; i < n; ++i)
nodes.push_back(new Node(arr[i], i));
stack<Node*> stk;
for (int i = 0; i < n; ++i) {
Node* lastPop = nullptr;
while (!stk.empty() && stk.top()->val > arr[i]) {
lastPop = stk.top();
stk.pop();
}
if (!stk.empty())
stk.top()->right = nodes[i];
if (lastPop)
nodes[i]->left = lastPop;
stk.push(nodes[i]);
}
Node* root = nullptr;
while (!stk.empty()) {
root = stk.top();
stk.pop();
}
return root;}
该方法确保每个节点最多入栈出栈一次,总时间复杂度为O(n)。
构建笛卡尔树后,RMQ(a, b)等价于查找节点a和b在树中的LCA。可通过以下步骤实现高效查询:
整体流程:原数组 → 构建笛卡尔树 → DFS生成Euler Tour → ST表预处理 → O(1) RMQ查询。
笛卡尔树适用于静态或半静态数据的RMQ场景,如:
注意点:
基本上就这些,掌握构建和转化思想后,配合ST表就能高效解决多数RMQ问题。
以上就是C++怎么实现一个笛卡尔树_C++数据结构与RMQ问题的高效解法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号