牛客练习赛81 D 小 Q 与树 (权值线段树+dsu on tree)

博客介绍了如何在带点权的有根树中求解Σmin(a[i],b[j])*dis(i,j)的问题。通过引入LCA(最近公共祖先)并使用权值线段树进行优化,实现了复杂度为O(n log n)的解决方案,详细解释了算法思路和代码实现。
摘要由CSDN通过智能技术生成

tp链接

在这里插入图片描述
min(a[u],a[v])*dis(u,v)这个式子带min函数,dis函数,都比较麻烦,肯定需要化简的。

trick:

  • dis(u,v)可以引入LCA,转化成dis(1,u) + dis(1,v) - 2*dis(1,LCA)
  • 对于min函数的处理,我们可以分类讨论,在rt子树中,把点权大于等于a[rt]的节点分为一类,小于a[rt]的节点分一类
  • 于是可以把式子写成:
    对于
    a x 1 , a x 2 , . . . a x c n t 1 > = a u a_{x1},a_{x2},...a_{xcnt1} >= a_{u} ax1,ax2,...axcnt1>=au
    贡献为:
    a u ∗ ( d e p [ a u ] + d e p [ a x 1 ] − 2 ∗ d e p [ L C A ] ) a_{u}*(dep[a_{u}]+dep[a_{x1}]-2*dep[LCA]) au(dep[au]+dep[ax1]2dep[LCA])
    + a u ∗ ( d e p [ a u ] + d e p [ a x 2 ] − 2 ∗ d e p [ L C A ] ) +a_{u}*(dep[a_{u}]+dep[a_{x2}]-2*dep[LCA]) +au(dep[au]+dep[ax
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值