[算法] Dsu on tree 与 线段树合并
学习笔记
Dsu on tree 树上启发式合并,一种运用于解决静态树上(每一颗子树)统计问题的思想,既然都叫启发式合并了,想到冰茶几的按序合并,将小的放到大的里面去,大的。。。小的。。。最大的。。。这不重链剖分嘛!
思考暴力怎么搞,不难想到一个很朴素的做法:递归全部儿子后,直接再次遍历整颗树,这样时间复杂度是 \(O(n^2 k)\),空间为 \(O(S)\)。(\(k\) 是修改单个值的复杂度)
它肯定是可以优化的(不然讲它干嘛),首先,我们珂以直接不选择走两次最后一颗子树,直接再最后一颗子树已经统计完的情况下递归整棵树,这最后一个儿子选什么呢?没错,就是根的 重儿子。
思考这样做的复杂度为什么不是 \(O(n^2)\):
对于每一个结点 \(x\),它要么是在前面递归儿子被走到,这样是 \(O(k)\) 的,每个点只会走到一次,因此复杂度 \(O(nk)\)。
但它还有可能在祖先 \(f\) 暴力搜整颗树的时候被访问,\(f\) 什么时候需要访问到它所在的子树?,显然是它到 \(f\) 路径上离 \(f\) 最近的那个点(记为 \(f^{+1}\))不是 \(f\) 的重儿子,此时边 \((f, f^{+1})\) 是一条轻边,所以它在暴力搜的时候会被搜到 \(O(\text{到 1 路径上有多少条轻边})\) 次,由于轻边传下去整颗子树的大小最少减半,所以轻边数量不超过 \(\log_2 n\),那么对于一个点复杂度就是 \(O(k \log n)\),总体复杂度 \(O(n k \log n)\)。
我qiao,这也太神奇了
亮出 模板题,这题直接开个桶统计,\(k=1\),总复杂度 \(O(n \log n)\)

浙公网安备 33010602011771号