Loading

Array Collapse

前言

\(C\) 快魔怔了, 还是先来打这个

思路

方法 \(1\) : 笛卡尔树

看到这种类 \(\rm{RMQ}\) 问题直接一个笛卡尔树起手, 恰好 \(p\) 是不重的, 那么更方便了啊

搞出树树挖下性质

例如样例中的

4
2 4 1 3

pAX41V1.md.png

你注意到每次删除操作相当于选择一个键值段, 然后只保留这一段的根节点, 但是这样子做不够完善, 例如这样的一个数据

pAX4wqA.md.png

你删除键值段 \(1 \sim 4\) , 那么留下的根节点 \(2\) 和一个没被删除的 \(4\) 还需要继续处理?

这种情况下应当怎么办?

我们考虑树形 \(\rm{dp}\) , 令 \(f_u\) 表示 \(u\) 子树 (柚子厨) 中的序列可能性

容易发现对于上面这种情况, 我们只需要加上 \(4\) 子树的可能性即可

我们考虑形式化的表示这些问题

\(f_{u, 0 / 1}\) 表示对于 \(u\) 的子树, 其中是否保留 \(u\) 的可能性数量

那么有

\[\begin{cases} \begin{aligned} & f_{u, 1} \gets \sum_{k = 0}^{1} f_{ls, k} \cdot \sum_{k = 0}^{1} f_{rs, k}\\ & f_{u, 0} \gets \left[ \exists fa_r \right] \cdot \sum_{k = 0}^{1} f_{ls, k} + \left[ \exists fa_l \right] \cdot \sum_{k = 0}^{1} f_{rs, k} \end{aligned} \end{cases} \]

简化一下, 去掉 \(0, 1\)

\[\begin{cases} \begin{aligned} & f_{u} \gets f_{ls} \cdot f_{rs}\\ & f_{u} \gets \left[ \exists fa_r \right] \cdot f_{ls} + \left[ \exists fa_l \right] \cdot f_{rs} \end{aligned} \end{cases} \]

这种代码就不写了, 并不困难

方法 \(2\) : 朴素 \(\rm{dp}\)

这种方法应该好想一点

你发现一个可以通过操作 \([l, r]\) 来保留两端的点, 仅有这两种可能:

  • \(a_l\)\([l, r]\) 区间中最小值
  • \(a_r\)\([l, r]\) 区间中最小值

简单分讨即可, 具体见 Luogu 题解

总结

笛卡尔树上常见的树形 \(\rm{dp}\)

posted @ 2024-12-23 20:57  Yorg  阅读(83)  评论(0)    收藏  举报