📅  最后修改于: 2023-12-03 14:56:38.540000             🧑  作者: Mango
笛卡尔树 (Cartesian Tree) 又称二叉树排序树,是一种特殊的二叉树,它满足以下条件:
笛卡尔树的应用非常广泛,其中包括最大化区间问题(Max-Interval-Query)等。在此介绍笛卡尔树的构建方法,以及一个应用案例。
笛卡尔树最常见的构建方法是使用单调栈,具体步骤如下:
笛卡尔树最常见的应用是最大化区间问题(Max-Interval-Query),具体问题可定义为:给定一个长度为 n 的序列 A,和一个值 k,要求找到 A 中长度最长的连续子序列,使得子序列中最大的数不超过 k。这个问题可以使用笛卡尔树来解决。
struct node {
int val, maxv;
node *l, *r;
void pushup() {
maxv = val;
if (l) maxv = max(maxv, l->maxv);
if (r) maxv = max(maxv, r->maxv);
}
}*root, pool[MAXN], *cur = pool;
stack<node*> stk;
inline node* newNode(int val) {
node* now = cur++;
now->val = now->maxv = val;
return now;
}
inline void Insert(int val) {
node* now = newNode(val);
if (stk.empty()) {
root = now;
} else {
if (val > stk.top()->val) {
stk.top()->r = now;
} else {
node* p;
while (!stk.empty() && stk.top()->val > val) {
p = stk.top(); stk.pop();
};
if (stk.empty()) {
now->l = p; root = now;
} else {
stk.top()->r = now; now->l = p;
}
}
}
stk.push(now);
}
int dfs(node* u, int k) {
if (!u) return 0;
if (u->maxv > k) return 0;
if (u->val > k) return dfs(u->l, k);
return dfs(u->r, k) + max(dfs(u->l, k), u->r ? u->r->rmaxv : 0) + 1;
}
int query(int k) {
return dfs(root, k);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int n, k;
cin >> n >> k;
for (int i = 1, x; i <= n; ++i) {
cin >> x;
Insert(x);
}
cout << query(k) << endl;
return 0;
}
返回的代码片段中,我主要展示了笛卡尔树的遍历方法,及基于笛卡尔树的应用——最大化区间问题的实现代码。同时,对代码中的重要变量及函数做出了简单的注释,在记录方法的讲解时也做了相应体现。