「树上启发式合并」
[摘自爱码网]
这种算法能够解决关于询问一棵树的子树的相关信息的问题。
算法的流程大概是这样:
1、dfs将一棵树建好,将节点的size、dfs序、重儿子、该dfs序对应的节点这些信息处理好(其他的信息具体问题具体分析)。
2、进入solve函数,先去解决非重儿子,然后将这些非重儿子的信息暴力清空。
3、接下来解决重儿子,这次不清空。
4、然后再将非重儿子的信息再暴力添加。
5、将该节点的信息添加进容器。
6、回答关于这个节点的问题。
7、返回。当然对于存信息的sum不一定是普通的数组,可能是map,可能是树状数组这类既支持插入又支持删除的容器,有适合的数据结构,而不是用数据结构去套题。
复杂度:
对于某个叶子节点来说,我们最终是要把它对答案的贡献加到根节点中,从而回答根节点的询问。可以知道,所有的节点其实都在重链上,
叶子节点到根节点的最多经过logn条轻边,我在将这个节点合并到根的时候,也顺便将别的节点合并到根上了,每合并一次,复杂度最多O(n)。
总的复杂度应该是O(nlogn)。
Keep it simple and stupid.