树上差分原理

树上差分常用在对路径权值的快速修改操作。

我们可以先借助线性差分来理解。

线性差分常用在线性修改区间的值,我们通过修改区间边界的值,起点加上值表示给后面的区间都加上权值,终点减去值表示为后面的区间都减去权值,为后面不应该受影响的区间抵消掉该影响。最后再做一个前缀和,则就能将差分值转化为每个点在修改后的权值了。

那么将线性差分转化为树上差分。

我们将线性差分中的"区间修改"概念理解为"树的两结点的路径上所有边的权值修改"。

则"起点加上值"概念可以理解为"一个结点到根节点的路径上所有边都加上权值",

"终点减去值"概念可以理解为"该结点与另一个结点的【最近公共祖先】到【根节点】的路径上的所有边都减去权值以抵消掉影响"。(求最近公共祖先可以看我的另一篇文章:最近公共祖先结点--LCA(倍增法,言简意赅)-CSDN博客

那么两结点的"区间修改"也就是“两结点的差分值各自+1,最近公共祖先的差分值每次-1(总共减2)"

 “前缀和”可以理解为“结点与其所有子树的权值之和”。

则前缀和就是该结点的入边的权值。

vector<int>son[N];
int br[N];//每个结点的差分值
int w[N];//点的入边的权值
//"区间修改"
void Path(int a,int b){
    br[a]++;br[b]++;
    br[lca(a,b)]-=2;
}
//计算"前缀和",即点的入边的权值
int getSum(int u,int p){
    for(auto it:son[u]){
        if(it!=p){
            w[u]+=getSum(it,u);
        }
    }
    return w[u];
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值