树上启发式合并学习笔记
Last Update:
Word Count:
Read Time:
之前一直搞不懂 Dsu on tree,今天终于懂了,很激动,遂记录下来。
看到一篇博客,说:Dsu on tree=树上不删除莫队,然后就恍然大悟了。
我们回顾一下 Dsu on tree 的算法流程:
- 先遍历 的轻儿子,计算它们自己的答案,然后把贡献删去。
- 遍历 的重儿子,保留贡献。
- 再次遍历轻儿子,加入这些点的贡献,得到 的答案。
事实上跟不删除莫队还是不太一样的,但是都是有回滚的思想在里面的。
但感觉这东西不太厉害啊,能用这个的题基本都有一堆其他方法做。
且局限性比较大,需要满足:
- 只有查询
- 只和子树有关
而且复杂度也不一定优,唯一优点可能是小常数+好写?
把之前线段树合并的题单拿过来再做一遍(从这就已经能看出它的可替代性了)。
树上数颜色
本质上是区间数颜色,做法很多。
因为要练 Dsu,所以写了 Dsu。
确实感觉这东西和莫队差不多。
复杂度 。
1 |
|
[USACO17JAN] Promotion Counting P
本质上是二维数点,做法很多。
考虑 Dsu,逆序对用树状数组求一下即可。
复杂度 。
1 |
|
Lomsat gelral
也是模板。
注意清空。
1 |
|
Blood Cousins
先跳到 级祖先上,那么问题变为:子树内颜色为 的点的个数。
相信大家都会写代码。
Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
又是 美好的每一天。
先处理出每个点到根的路径上每种字符出现次数的奇偶性,设为 。
点对 合法,当且仅当 至多有一个 。
设当前处理到点 ,显然以 为根的子树的答案分两部分:以 为 的路径和不以 为 的路径。
后面一部分只需要和儿子取 即可,考虑前一部分怎么算。
设点 为一对合法点对,则其贡献为 。
我们扫 ,然后维护 。
具体的,我们维护一个 ,表示 的最大的 。
在遍历到一个儿子 时,我们枚举哪一位为 ,若合法则更新答案。
删除轻儿子的贡献时,直接把对应的 清空即可。
复杂度 。
注意:计算答案时是类似点分治一样,算完这颗子树再把它合并进来,因为这样才能保证路径的 为 。
1 |
|
Dominant Indices
思路和线段树合并的思路完全一样。
统计每个深度出现次数,然后取最大即可。
记得减一下。
Tree and Queries
套个树状数组支持查询即可。
复杂度 。
但事实上完全不需要这个树状数组,只需要开个桶即可。
具体的,维护一个数组 ,表示出现次数 的颜色数,然后再开一个数组维护每种颜色出现次数,就做完了。
Tree Requests
对每个深度维护每种字符出现次数的奇偶性即可。
复杂度 。
Blood Cousins Return
每个深度开个 set 即可。
注意是森林。
复杂度 。