树链剖分与线段树

一 说明

在树中进行点更新、区间更新、区间查询等操作,可以使用线段树来维护和处理。

二 图解

一棵树如下图所示。

树链剖分之后的节点序列和下标序列如下图所示。

节点序列对应的权值如下图所示。

根据 w[] 序列创建线段树,如下图所示。

查询节点 u 到 v 路径上节点权值的最值与和值的方法如下。

• 若 u 和 v 在同一条重链上,则在线段树上查询其对应的下标区间 [id[u ],id[v ]]即可。

• 若 u 和 v 不在同一条重链上,则一边查询,一边将 u 和 v 向同一条重链上移。对于顶端节点深度大的节点,先查询其到顶端节点的区间,然后一边上移一边查询,直到上移到同一条重链上,再查询在同一条重链上的区间。

查询节点 6~9 权值的最值与和值(包括6和9节点),过程如下。

1 读取 top[6]=1,top[9]=2,两者不相等则说明其不在一条重链上,且 top[9]的深度大,先查询 top[9]~9之间的最值与和值。

首先得到节点 2 和 9 对应的节点序列下标 7 和 9。

然后在线段树中查询 [7, 9] 区间的最值与和值。[7,9] 区间的最值与和值:Max=15,Sum=22。

2 将 u 上移到 top[9](2号节点)的父节点,即 1 号节点,此时 1 和 6 在同一条链上。

节点 1 和 6 对应的线段树下标为 1 和 3。

在线段树中查询到 [1, 3] 区间的最值与和值分别为 20、31,如下图所示 。 再与前面的结果求最大值与和值 , 则 Max=max(Max,20)=max(15, 20)=20,Sum=Sum+31=22+31=53。

区间更新的方法与此类似,若不在一条链上,则一边更新,一边向同一条链上靠,最后在同一条链上更新即可。

注意:更新和查询时均需要先得到节点对应的线段树下标,再在线段树上更新和查询。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值