【学习笔记】笛卡尔树
笛卡尔树
介绍
笛卡尔树是一种二叉树,每一个节点由一个键值二元组 \((k,w)\) 构成,其中 \(k\) 满足二叉搜索树的性质,而 \(w\) 满足小顶堆的性质
性质
1.两个维度的键值分别满足 BST 和小顶堆的性质
2.题目中往往用数组下表当作 \(k\) 因此笛卡尔树每一个节点子树的下标都是连续的
代码
如果只是朴素构造,每天添加一个点,就会被加到右链(从根节点到最右叶节点的路径所形成的链)的末端,会使树退化成一条链。
所以每次添加新点时这么做
- 从下往上遍历右链,找到一个 \(v\) 使得 \(w_v<w_x\)
- \(v\) 的右儿子变为 \(x\)
- 将 \(v\) 原来的右儿子变为 \(x\) 的左儿子
由于 \(k\) 经常为数组下标,所以其单调递增,因此每个节点最多出入右链一次,所以可以用单调栈维护,时间复杂度 \(O(n)\)
void insert(int x){
int k = top;
while(k && p[st[k]] >= p[x]) k--;
if(k) rs[st[k]] = x;
if(k < top) ls[x] = st[k + 1];
st[++k] = x;
top = k;
}

浙公网安备 33010602011771号