其他分享
首页 > 其他分享> > 笛卡尔树学习笔记

笛卡尔树学习笔记

作者:互联网

众所周知,笛卡尔树是联赛考纲内的内容

定义

笛卡尔树是一种二叉树,每一个结点由一个键值二元组(k,w)构成。要求k满足二叉搜索树的性质,而w满足堆的性质。
如果k,w已知,且互不相同,则符合定义的笛卡尔树唯一。

线性建树

如果序列的第一维有序,我们可以利用单调栈在O(n)的时间内完成笛卡尔树的构建。
不妨假设第一维降序排序,以小根堆为例,每当我们向树中插入一个权值,为了满足二叉搜索树性质,其必然插入在树的右链。如果它的父亲节点第二维大于其第二维的值,我们对该节点进行左旋操作(不明白的话请参考讲解平衡树的博客的),直至其满足堆的性质。
如果你学过Treap,会发现这就是Treap的操作(事实上,Treap就是一种笛卡尔树)
因为每个节点最多在右链上出现一次(左旋之后父亲节点被移到了左链上),我们使用单调栈来维护其右链上的节点。
代码:

点击查看代码
void build() {
	for(int i=1;i<=n;i++) { 
		cur=top;
		while(cur && a[s[cur]] > a[i]) cur--;
		if(cur) r[s[cur]]=i;
		if(cur < top) l[i]=s[cur+1];
		s[++cur]=i;
		top=cur;
	}
}

一般情况建树

我们对第一维排序后,即可使用上述算法建树。
代码略

标签:cur,笛卡尔,笔记,建树,学习,Treap,节点,树是
来源: https://www.cnblogs.com/cbxz/p/15490337.html