[蓝桥杯学习]树上差分

差分

前缀和 sum_i = sum_i-1 + a_i

差分 diff_i = a_i - a_i-1

差分的好处

点的差分

问题引入
解决问题

要用到差分的思想,每次从叶子向上的回溯,让父结点+=子结点的cnt值,但是仅仅这样,还不行

回溯的过程中,LCA被加了两次,要减去一,LCA的父结点原本应该没有数值的,但是因为会加上LCA 的值,所以会多1,要减去。

此上操作,便实现了,只是把s t 两个结点的值赋一,便将s到t路径上的点经过次数赋值为1

代码实现

cnt计算的代码实现,如下

cpp 复制代码
void dfs1(int x){
    for(int i=head[x];i;i=edge[i].nex){
        int u=edge[i].to;
        if(u!=fa[x][0]){
            dfs1(u);
            cnt[x]+=cnt[u];
        }
    }
    return ;
}

cntx+=cntu ,在dfs1 之后,就是从子结点回到父结点后进行cnt相加。

边的差分

问题引入

将路上每条边都权值加z

解决问题

把边塞给点,边的权值放在点上,使用差分的方法,每次修改都是O(1)的时间复杂度,将最后的结果最坏下是O(n)遍历要求的区间,就可以得到区间权值和。

解释为什么要把 dltlca(u,v)-=2x

因为根据方法,回溯时父结点会加上子结点的权值,所以LCA会加上左右两边的孩子的权值(即边的权值),根据我们给点权值的定义,意思是,会经过该边两次,但是该边没有经过两次,所以会减去2x

代码实现

与点上的差分一样的

时间复杂度分析

维护的时间复杂度是O(1),最后dfs一遍统计答案,最坏时间复杂度是O(n)

相关推荐
熊猫钓鱼>_>4 小时前
ArkTS 装饰器总览:V1 / V2 / 通用装饰器完整学习笔记
笔记·学习·华为·交互·harmonyos·arkts·arkweb
茯苓gao7 小时前
嵌入式开发笔记:CAN与CAN FD完全指南——从帧格式差异到MCU选型实战
网络·笔记·stm32·嵌入式硬件·学习·汽车
木木_王7 小时前
嵌入式学习 | STM32 裸板驱动开发(Day06) | DHT11温湿度传感器超详解(单总线时序+全套驱动代码+智能温湿度报警项目)
驱动开发·stm32·学习
FellAveal8 小时前
【Go语言入门学习笔记】Part19.速率控制、原子计数器、互斥锁(Mutex)、状态协程
笔记·学习·golang
你怎么知道我是队长8 小时前
经典蓝牙(Bluetooth Classic / BR/EDR)学习计划
学习
极地野狼 音乐哔哔8 小时前
[MAF预定义的AIContextProvider-03]ChatHistoryMemoryProvider——赋予Agent从经验中学习的能力
学习·microsoft
oier_Asad.Chen10 小时前
【洛谷题解/AcWing题解】洛谷P4011 孤岛营救问题/AcWing1131拯救大兵瑞恩
数据结构·笔记·学习·算法·动态规划·图论·宽度优先
xxwl58511 小时前
Git 完整学习笔记:从入门到团队协作
笔记·git·学习
minglie111 小时前
zynq的xlnx_rebase_v5.4_2020.2分支打patch-5.4.3-rt1.patch.xz补丁
学习
醉城夜风~12 小时前
HTML常用标签详解学习博客:从基础标签到页面结构完整掌握
前端·学习·html