「树上启发式合并」

[摘自爱码网]

这种算法能够解决关于询问一棵树的子树的相关信息的问题。

算法的流程大概是这样: 
1、dfs将一棵树建好,将节点的size、dfs序、重儿子、该dfs序对应的节点这些信息处理好(其他的信息具体问题具体分析)。 
2、进入solve函数,先去解决非重儿子,然后将这些非重儿子的信息暴力清空。 
3、接下来解决重儿子,这次不清空。 
4、然后再将非重儿子的信息再暴力添加。 
5、将该节点的信息添加进容器。 
6、回答关于这个节点的问题。 
7、返回。 

当然对于存信息的sum不一定是普通的数组,可能是map,可能是树状数组这类既支持插入又支持删除的容器,有适合的数据结构,而不是用数据结构去套题。

复杂度:

对于某个叶子节点来说,我们最终是要把它对答案的贡献加到根节点中,从而回答根节点的询问。可以知道,所有的节点其实都在重链上,

叶子节点到根节点的最多经过logn条轻边,我在将这个节点合并到根的时候,也顺便将别的节点合并到根上了,每合并一次,复杂度最多O(n)。

总的复杂度应该是O(nlogn)。

posted @ 2019-07-30 14:38  _xuefeng  阅读(151)  评论(0编辑  收藏  举报