Coding on 树上倍增

树上倍增 技巧及题单

Posted by Kylin on August 27, 2023

[TOC]

树上倍增

适用场景:寻找一棵树的k代祖先,可以类似二次幂的思路。初始化每一个节点的 1,2,4,log(h) 代祖先,这样的话,初始化复杂度为 O(n log h) 。之后寻找k代祖先的单次查找复杂度为 O(log k),适用于多次查询的场景

Template(以 leetcode 2836 为例)

class Solution {
public:
    long long getMaxFunctionValue(vector<int>& receiver, long long k) {
    	n = len(reveiver)
    	// 定义最大查找长度,1<<0为父亲,1<<(k.bit_length()-1)
        m = k.bit_length()-1
        pa = [[(p,p)]+[None]*m for p in receiver]
        for i in range(m):
        	for x in range(n):
        		// 寻找节点 x 的 1<<i 代祖先p和cost
        		p,s = pa[x][i]
        		// 寻找节点 p 的 1<<i 代祖先pp和cost
        		pp,ss = pa[p][i]
        		// 那么节点 x 的 1<<(i+1) 代祖先就是pp,cost就是代之间的加和
        		pa[x][i+1] = (pp,s+ss)
        		
     	res = 0
     	for i in range(n):
     		// 遍历每一个节点
     		sum = 0
     		x = i
     		for j in range(m+1):
     			//遍历k的每一个二级制位
     			if (k>>j)&1:
     				// 若 1<<j 代祖先存在,则将当前节点迭代至 1<<j 代祖先
     				x,s = ps[x][j]
     				// 累计 cost 加和
     				sum += s
     		res = max(res,sum)
     	return res
    }
};

Leetcode 题单