一、定义
将一个序列构造成满足如下条件的一棵树:
- 父节点比子节点小(大)
- 树的中序遍历,与原序列相同
[6, 2, 8, 1, 7, 3, 5]这个序列可以建成如下图所示的笛卡尔树。
二、构造
- 将根、根的右子树、根的右子树的右子树……加入栈内
- 插入新元素时,将栈内比当前元素大的元素弹出,然后将当前元素作为栈顶元素的右子树,栈中最后一个被弹出的元素为该元素的左子树。将该元素插入栈内。
- 注意当前元素没有左子树或当前元素为根的情况。
void build()
{
rt = 1;
stk[1] = 1;
int top = 1;
for(int i = 2; i <= n; i++)
{
while(top && p[stk[top]] > p[i])
{
l[i] = stk[top];
top--;
}
if(top) r[stk[top]] = i;
else rt = i;
stk[++top] = i;
}
}
三、查询
查询区间最小值即为查询LCA。(但是好像没什么用,毕竟rmq也可以做到,还比它好写,所以笛卡尔树的应用主要在构造上)