树链

树链剖分(heavy path decomposition,轻重路径剖分),我个人认为,相比起称之为一种“算法”,更像是一种处理树的相关问题时的一种方法,技巧。
其实,真正的树链剖分,应该是套个线段树进行维护的。不过,那个我并不会。所以这里写的是“树链”,真实面目其实应该是某种启发式合并。

首先,定义结点的 size 值为以该结点为根的子树的结点数。
给定一棵有根树,对于每个非叶子结点 u ,设 u 的子树中 size 最大的子树的树根为 v ,则标记 (u,v) 为重边, u 向其他儿子的边均为轻边,如下图所示。

根据上面的定义,只需一次 DFS 就能把一棵有根树分解成若干重路径(重边组成的路径)和若干轻边。

路径剖分有两条重要定理:

  1. 对于 u 的子结点 v ,当 (u,v) 为轻边时, size(v)<size(u)÷2
    理由:根据定义,所有非叶结点往下都有一条重边。不妨假设 size(v)size(u)÷2 ,则对于 u 向下的重边 (u,v) 来说, size(v)size(v)size(u)÷2 ,可得 size(u)1+size(v)+size(v)size(u)+1 ,与假设矛盾。

    • 由定理 1 得,对于任意非根结点 u ,在 u 到根的路径上,轻边和重路径的条数均不超过 log2n ,因为每碰到一条轻边, size 值就会减半。
    • 这样,在处理一类统计子树相关问题时,可以采用如下策略:

      • 从所有叶子结点出发向上考察
      • 每当到达一个结点时,要计算其各子树对当前总子树的答案贡献。对于重儿子(以重边连接的儿子),直接将其答案累加。对于轻儿子,dfs暴力统计。

      对于重儿子,显然计算效率会比较高。但轻儿子的暴力统计呢?这样会不会导致超时?

      其实是不会的。根据定理 2 可知,每个结点到根结点的路径上最多不会存在超过 log2n 条轻边,即,每个结点最多被统计 log2n 次。这样,总的时间复杂度其实只有 O(nlog2n) 。而对于真正的套上线段树的树链剖分,由于线段树的操作也是 log 级别的,因此复杂度还要再套一个 log,为 O(nloglogn)

      直接这样讲会感觉很抽象,所以还是要通过例题来说明。详见《树》解题报告

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值