笛卡尔树模板

定义:

笛卡尔树是一种二叉树,每一个节点由一个键值二元组((k,w))构成,要求(k)满足二叉搜索树的性质,而(w)满足堆的性质

构建:

我们考虑按照键值(k)排序,然后一个一个插入到当前的笛卡尔树中(这样就保证了他一定满足二叉搜索树的性质),且每次我们插入的元素一定在这个树的右链(右链:即从根结点一直往右子树走,经过的结点形成的链)的末端,于是我们我们执行这样一个过程,从上到下比较右链节点与当前节点(u)(w),如果找到一个右链上的节点(x)满足(x_w<u_w),就把(u)接到(x)的右儿子上,而(x)原本的右子树就变成了(u)的右子树,这样就可以保证堆的性质

显然每个数最多进出右链一次(或者说每个点在右链中存在的是一段连续的时间)。这个过程我们可以用栈维护,栈中维护当前笛卡尔树的右链上的结点。一个点不在右链上了就把它弹掉。这样每个点最多进出一次,复杂度(O(n))

code

int top = 0;
for (int i = 1;i <= n;i++){
	int k = top;
	while (k > 0&&a[st[k]] > a[i]) k--;
	if (k) rs[st[k]] = i;
	if (k < top) ls[i] = st[k+1];
	st[++k] = i;
	top = k;
}
原文地址:https://www.cnblogs.com/little-uu/p/14019840.html