笛卡尔树学习笔记

定义

笛卡尔数是通过一个序列构造出来的树。满足以下性质:

  1. 是一棵二叉树。
  2. 中序遍历结果是 \(1 \sim n\)
  3. 对于每一个非根节点,权值大于/小于父亲的权值。

来自 OI Wiki 的一张图。

性质

  1. 任意一条深度单调的路径,权值单调。
  2. 对于任意两点 \(u<v\),满足以 \(\text{lca}(u,v)\) 为根的子树包含下标 \([u,v]\) 的区间。

构建

维护最右边的一条链,这条链编号和权值都单调,可以把这条链看作单调栈。
从前向后遍历 \(a\) 数组,对于每一个 \(i\) 执行:
如果 $a_i \ge a_{stack_{top}} $,直接入栈。
否则,一直弹出栈顶直到栈空或者 $a_i \ge a_{stack_{top}} $,入栈,最后一个弹出的栈顶设为 \(i\) 的左儿子。

for(int i=1;i<=n;i++){
    int top=tot;
    while(top&&v[st[top]]>v[i]) top--;
    if(top) rc[st[top]]=i;
    if(top<tot) lc[i]=st[top+1];
    st[tot=++top]=i;
}

应用

  1. RMQ 问题。
  2. 优化 dp。
    \(\cdots\)
posted @ 2024-12-31 15:12  革命军参谋长·萨博  阅读(19)  评论(0)    收藏  举报