【学习笔记】笛卡尔树

笛卡尔树

介绍

笛卡尔树是一种二叉树,每一个节点由一个键值二元组 \((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;
}
posted @ 2024-12-19 15:57  GuoSN0410  阅读(37)  评论(0)    收藏  举报