笛卡尔树初学

学了新算法,不管怎么样也要记录一下吧

笛卡尔树有以下两个特点:
1.是一个堆结构

2.它的中序遍历顺序等于原序列的顺序

性质:

[i,j]区间的最值等于lca(i,j)的值

如何构建?

首先先建一个0号节点,a[0]=inf

然后构建一个栈,来维护右链

栈底为root,s[top]是s[top-1]的右儿子

考虑加入元素k

判断两种情况:

  1. 它比栈顶还大。因为是单调栈,可以直接加到栈顶。
  2. 它不比栈顶大。我们只需要在栈里找到它插入的位置,把比它大的一段链全都变成它的左子树,然后再把它插入。这样,在中序遍历的时候仍然是先遍历其左子树再遍历它自身,满足第二条性质;因为左子树都比它大,显然满足性质

代码如下:

a[0]=1e9;s[top=1]=0;
for (int i=1;i<=n;i++){
    while (top&&a[s[top]]<a[i]) top--;
    int x=s[top];
    fa[i]=x;
    l[i]=r[x];
    fa[r[x]]=i;
    r[x]=i;
    s[++top]=i;
}

 

posted @ 2018-09-06 13:49  longint  阅读(120)  评论(0编辑  收藏  举报