树链剖分学习小记

树链剖分

在处理一类在树上修改,查询的问题时,我们往往需要把这棵树剖分成一个序列。然后利用数据结构在这个序列上把你所需要的东西一段一段地查出来。但如果剖分方法不得当的话,每一次查询就可能只查询了一个点,时间复杂度还不如暴搜!因此我们需要一个优秀的算法来帮助我们进行剖分,这就是树链剖分(启发式剖分,轻重链剖分)。

我们把每一个点最大的儿子叫做重儿子,其余的叫做轻儿子。连接重儿子的叫做重边,其余的叫做轻边。由重边组成的链叫做重链,由轻边组成的链叫做轻链。然后对于每一条重链,它上面的点在线段树里的编号都是连续的。这样就能解决问题了(因为我们保证了一个树上路径被分成了尽量少块)。

现在来讲讲怎么打。
对于每一个点x,我们用top[x]表示它所在的重链的顶端节点,fa[x]表示它的父亲,w[x]表示它在线段树中的位置(用来修改),size[x]表示以它为根的子树的大小(用来求son),son[x]表示它的重儿子,d[x]表示它的深度。这些东西可以用两遍dfs求出。
然后对于询问x,y。我们设f1=top[x],f2=top[y],然后查找w[f1]到w[x]的答案,并把x=fa[f1],f1=top[x]。然后每一次如果d[f1]< d[f2]就把x和y,f1和f2交换(方便计算,我有点懒)。最后再把x到y的答案统计一下就行了。

例题

【ZJOI2008】树的统计
【SDOI2014】旅行
【GDOI2103模拟3.17】数树数

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值