树上合并 目前的总结

启发式合并(set)

元素少的 set 中的元素一一插入元素多的 set 中。

时间两只 \(\log\)。空间最坏为 \(n\) 这个级别(结点数)(这是在默认一个结点最多增加一个元素的情况下)。

log 数据结构时间也是两只 \(\log\)

dsu on tree

好像[也叫“树上启发式合并”](??)。

[一般](?)是重链剖分一样划分轻重儿子。(好像也有与长链剖分类似的写法。但我不会也不懂这有什么优势。下面今天写的内容都是指重链剖分。)

实际上是靠保留重儿子子树的影响,轻儿子的子树只是临时用(当然如果上面有重儿子也会被保留)。

这样保证了时间和空间,时间复杂度的分析类似于重链剖分。而且 可以用桶这种占用空间较多的东西来维护,虽然不用桶用 set 应该也可以。用桶时间是一只 log 的,用 set 时间是两只 log。基本的空间是 \(n\) 这个级别的,如果用桶则空间还要加上桶的。

下面是一些实现细节:

  • 先走轻儿子可以保证重儿子的子树不会影响到轻儿子的子树。

  • dsu on tree 主要是添加,删除本质上是“追溯”。于是遇到不能快速回退(没法快速整上一个逆)的情况,可以记一下之前的某个变量,之后还原回去(如:[CF600E](?)),而不用真正一步步还原。如果一步步还原应该可以用栈来实现(如果要还原桶空间可能很大),虽然我应该还没有遇到这种题。一步步还原本质上应该是用[“可追溯化”](???)数据结构来维护。如果直接跳回之前的状态(不是一步步回去)可以用主席树这种可持久化数据结构来维护。

线段树合并

Trie 合并、[李超线段树合并](我还不会,不确定属不属于)大概也属于线段树合并。

线段树相比平衡树的优势在于它结构固定。这使得它可以快速地合并(指的是可以有交集的合并),而平衡树没法快速地合并(指的是有交集的)。

树状数组好像正常来看不太好合并,因为它一般不是一个[“纯函数式”](?)的结构。但是好像它本来就是一棵树(还是森林????),所以应该也可以做(????)。

线段树合并用的是动态开点线段树。

线段树合并时间是单 log 的。时间复杂度分析 好像 是每次合并删掉多少点什么的,忘了。合并不会新建点,所以合并不会增大空间,空间是一开始的 log * n 级别的(在每个结点只有一个元素的情况下)。

线段树合并相当于把两棵线段树的信息相加。这可以用来优化那种形如 \(f_{u,i} = (v \in ch_u) f_{v,i} \cdots\) 的 DP,(我好像现在只会二叉树(最多只有两个儿子)的,但应该儿子更多也是一样的吧(如果 DP 没有什么其他的限制,其他限制比如 DP 方程里要求乘上另一个儿子的什么东西)?)即直接把信息拿上来(位置是不变的)再做修改。同时线段树支持[区间乘](?)[这种](?)操作,可以快速地修改。还可以也利用线段树的其他东西来优化这种 DP。例题是 [PKUWC Minimax](?)。

李超线段树可以优化把李超线段树优化 DP 或者斜率优化 DP 搬到树上的 DP。例题好像是 CF 上一题,可以去今天的 PPT 里或者题单里找。

2024.8.19

posted @ 2024-08-19 22:50  huangkxQwQ  阅读(5)  评论(0编辑  收藏  举报