【算法学习02】树上倍增

树上倍增模版

详细见灵神题解

【模板讲解】树上倍增算法

代码模版(python)

#n是节点个数,parent是父节点数组
def __init__(self, n: int, parent: List[int]):
    m = len(bin(n)[2:])-1 #m表示最多能往上数多少个祖先
    #开辟st表数组 p[x][i]表示x节点的2^i个祖先
    pa = [[p] + [-1]*m for p in parent]
        for i in range(m):
            for j in range(n):
                p = pa[j][i]
                if p!=-1:
                    #j节点的2^(i+1)个祖先相当于是j的2^i个祖先的2^i个祖先
                    pa[j][i+1] = pa[p][i]
    self.pa = pa

相关题目练习

【leetcode】1483.树节点的第k个祖先

        题目描述

         数据集范围

 

        思路

        对于寻找某一节点的k次祖父节点,显然最暴力的做法就是对于该节点进行k次循环不断往上寻找祖父节点,时间复杂度为O(mn),m为查询次数,这显然对于该题的数据范围是不可取的。考虑到快速幂算法与本题有相似之处,因此可以用倍增的思想来优化时间复杂度。对于某一节点x,记录其向上跳了2^i次后的节点为pa[x][i],很自然的可以得到对于跳了2^(i+1)次之后的节点,即pa[x][i+1]x节点跳了2^i后得到的节点再跳2^i次得到的节点,即pa[x][i+1]=pa[pa[x][i]][i]。因此我们只需要在开始的时候用O(nlogn)的时间初始化pa数组,即可以在每次查询用O(logk)的时间获取k次祖父节点。因此本题的总时间复杂度从O(mn)优化到了O(nlogn+mlogk)。

        代码实现

class TreeAncestor:

    def __init__(self, n: int, parent: List[int]):
        m = len(bin(n)[2:])-1
        pa = [[p] + [-1]*m for p in parent]
        for i in range(m):
            for j in range(n):
                p = pa[j][i]
                if p!=-1:
                    pa[j][i+1] = pa[p][i]
        self.pa = pa 

    def getKthAncestor(self, node: int, k: int) -> int:
        bit = str(bin(k)[2:])
        deep = 0
        for b in bit[::-1]:
            if b == '1':
                node = self.pa[node][deep]
            if node == -1:
                break
            deep+=1
        return node

 【leetcode】2836.在传球游戏中最大化函数值

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值