树上差分(点差分/边差分)

树上差分一般有两种类型的题目,一种是对边进行差分,另一种就是对点进行差分

对应的操作也有两种,对边进行差分的对应操作就是给定一对节点(u,v),让我们把u到v之间路径上的边权都加val,对点进行差分的对应操作就是给定一对节点(u,v),让我们把u到v之间路径上所经过的点的点权都加val,这两种操作是类似的,但又不完全一样,下面分别讲解一下这两种问题应该如何处理。

首先先来说一下将u到v之间路径上的边权都加val应该怎么处理。

以这个图为例子,我们假如要将1到2之间路径上的边权都加val,那么我们可以将边权唯一地对应到点权上,什么意思呢?因为对于树上的任意一个节点都有其对应的深度,那么对于同一条边所连接的两个节点的深度又是不同的,所以我们可以定义一条边权为以其连接的两个节点中的深度较大的节点为根的子树中所有节点的点权和,这样我们就可以唯一地确定每条边的边权。
那么我们要是想要把1到2之间路径上的边权都加val,我们可以把1号节点和2号节点的点权都加上val,这样凡是子树中包含节点1或2的节点的权值都会对应地加上val,我们只需要回溯的过程中更新一下以每个节点为根的子树中的节点点权之和即可,但是我们可以发现1和2的最近公共祖先3点权加了2*val,但是3号节点的点权是3号节点与其父节点之间的边权,不属于1和2之间路径的边权,所以我们应该将1和2的最近公共祖先点权减少2*val。这样就完成了更新。

还有一种常见操作就是点差分,还是以上面那个图为例,我们现在要将1到2的路径上的所有节点的权值加val,那么我们定义点权和上面边差分类似,定义一个节点的点权为以节点为根的子树中所有节点的点权和,那么我们现在要想将1到2的路径上的所有节点的权值加val,我们依旧可以先将节点1、2的点权+val,然后同理我们可以发现1和2的公共祖先3的点权相当于+2*val,但由于3号节点也属于1到2的路径上的节点之一,所以我们只需要减去val即可,但是这还不算结束,因为3号节点的父亲节点不属于1到2的路径上的节点之一,但是因为3号节点的点权加了val,而3号节点又是3号节点的子树中的节点,所以我们还应该把其父亲节点的权值减去val,这样才算是操作结束。

下面给出一道对应习题及其代码:

题目连接:P3128 [USACO15DEC]Max Flow P - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

样例输入: 

5 10
3 4
1 5
4 2
5 4
5 4
5 4
3 5
4 3
4 3
1 3
3 5
5 4
1 5
3 4

样例输出:

9

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
const int N=2e5+10;
int h[N],e[N],ne[N],idx;
int f[N][25],d[N],s[N];
void add(int x,int y)
{
	e[idx]=y;
	ne[idx]=h[x];
	h[x]=idx++;
}
void dfs(int x,int fa,int dd)
{
	d[x]=dd;
	f[x][0]=fa;
	for(int i=1;i<=20;i++)
		f[x][i]=f[f[x][i-1]][i-1];
	for(int i=h[x];i!=-1;i=ne[i])
	{
		int j=e[i];
		if(j==fa) continue;
		dfs(j,x,dd+1);
	}
}
int lca(int x,int y)
{
	if(d[x]<d[y]) swap(x,y);
	for(int i=20;i>=0;i--)
	if(d[f[x][i]]>=d[y]) x=f[x][i];
	if(x==y) return x;
	for(int i=20;i>=0;i--)
	if(f[x][i]!=f[y][i])
	{
		x=f[x][i];
		y=f[y][i];
	}
	return f[x][0];
}
void update(int x,int fa,int &ans)
{
	for(int i=h[x];i!=-1;i=ne[i])
	{
		int j=e[i];
		if(j==fa) continue;
		update(j,x,ans);
		s[x]+=s[j];
	}
	ans=max(ans,s[x]);
}
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		h[i]=-1;
	for(int i=1;i<n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y);add(y,x);
	}
	dfs(1,0,1);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		int t=lca(x,y);
		s[x]++;s[y]++;
		s[t]--;
		s[f[t][0]]--;
	}
	int ans=0;
	update(1,0,ans);
	printf("%d",ans);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/12334.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MYSQL数据库

目录 SQL SQL-DDL 操作数据库 查询&#xff08;show&#xff09;&#xff08;select&#xff09; 创建&#xff08;create&#xff09; 删除&#xff08;drop&#xff09; 操作表 查询当前数据库所有表 修改表 删除 SQL-DML 添加数据&#xff08;可以批量添加&…

课程简介:.Net Core从零学习搭建权限管理系统

课程简介目录 &#x1f680;前言一、课程背景二、课程目的三、系统功能四、系统技术架构五、课程特点六、课程适合人员七、课程规划的章节八、最后 &#x1f680;前言 本文是《.Net Core从零学习搭建权限管理系统》教程专栏的导航站&#xff08;点击链接&#xff0c;跳转到专栏…

做好Python工程师,首先你需要做好的几件事

做好Python工程师&#xff0c;需要做好的几件事&#xff0c;我想分享给大家。首先千万不要做事周折。在你提问之前&#xff0c;先好好想一想&#xff0c;这个问题自己能不能解决。如果能解决&#xff0c;尽量自己解决&#xff1b;如果解决不了&#xff0c;那就要把你的问题描述…

亿发软件:传统食品饮料批发行业如何通过信息化管理系统降本增效?

传统食品饮料批发行业信息化水平较低&#xff0c;存在多重管理难题&#xff0c;例如&#xff1a; 手动数据输入和管理&#xff0c;导致错误和效率低下&#xff1b; 数据缺乏实时可见性&#xff0c;无法实时了解企业仓库存量、销售额和其他关键业务指标&#xff1b; 低效的供应链…

索引:索引知识重复习,什么是索引、索引的类型、建立索引及【最左匹配原则】、Explain查看sql的执行计划

文章目录 什么是索引索引的类型主键索引&#xff08;primary key&#xff09;普通索引&#xff08;index&#xff09;复合索引全文索引&#xff08;fulltext&#xff09;空间索引唯一索引索引修改及删除 Explain一、using filesort(减慢查询效率)二、Using temporary三、using …

前端UI框架有哪些|20个优秀免费开源的WEB前端UI框架提高网站开发效率

最近准备学习一下前端UI我也是在网上找了很久最终整理出来了20个不错的前端UI框架网站,大家都知道很多成熟的前端框架可以直接引,学习框架可以提升我们网站的开发速度。有些大型公司的前端或者后端框架都是用自己开发的,对于大部分用户和公司来讲,我们可以用开源免费的前端…

Python 中 SyntaxError: ‘yield‘ outside function 错误

当我们在函数外部使用 yield 关键字时&#xff0c;会出现 Python “SyntaxError: ‘yield’ outside function”。 要解决该错误&#xff0c;如果我们需要对每个元素执行一些运算符&#xff0c;请使用列表理解&#xff0c;或者缩进函数内部使用 yield 的代码。 下面是一个产生…

毕业2年,跳槽到下一个公司就25K了,厉害了···

本人本科就读于某普通院校&#xff0c;毕业后通过同学的原因加入软件测试这个行业&#xff0c;角色也从测试小白到了目前的资深工程师&#xff0c;从功能测试转变为测试开发&#xff0c;并顺利拿下了某二线城市互联网企业的Offer&#xff0c;年薪 30W 。 选择和努力哪个重要&a…

写博客8年与人生第一个502万

题记&#xff1a;我们并非生来强大&#xff0c;但依然可以不负青春。 原本想好好写一下如何制定一个目标并通过一点一滴的努力去实现&#xff0c;这三年反思发现其实写自己的经历并不重要。 很多人都听过一句话&#xff1a;榜样的力量是无穷的。 更现实和实际的情况是&#x…

mysql聚合函数

文章目录 前言一、常见的聚合函数1.avg和sum函数2.max和min函数3.count函数 二、group by的使用1.基本使用方法2.with rollup 求平均值 三、having关键字的使用四、多表连接聚合函数1.sql92语法总结2.sql99语法总结 总结 前言 聚合函数&#xff1a;他是对一组数据进行汇总的函…

3 个自定义防抖 Hooks 的实现原理

前言— 本文通过实现 useDebounceFn、useDebounce、useDebounceEffect 3 种自定义防抖 Hooks&#xff0c;来介绍在日常开发过程中自定义 Hooks 的思路及实现&#xff0c;帮助大家完成通用 Hooks 来提高开发效率。 防抖— 防抖的概念已经司空见惯了&#xff0c;这里稍作简单介…

Golang每日一练(leetDay0034) 二叉树专题(3)

目录 100. 相同的树 Same Tree &#x1f31f; 101. 对称二叉树 Symmetric Tree &#x1f31f; 102. 二叉树的层序遍历 Binary Tree Level-order Traversal &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一…

程序设计方法学

体育竞技分析 问题分析 体育竞技分析 需求&#xff1a;毫厘是多少&#xff1f; 如何科学分析体育竞技比赛&#xff1f; 输入&#xff1a;球员的水平 输出&#xff1a;可预测的比赛成绩 体育竞技分析&#xff1a;模拟N场比赛 计算思维&#xff1a;抽象 自动化 模拟&am…

【算法题】2583. 二叉树中的第 K 大层和

题目&#xff1a; 给你一棵二叉树的根节点 root 和一个正整数 k 。 树中的 层和 是指 同一层 上节点值的总和。 返回树中第 k 大的层和&#xff08;不一定不同&#xff09;。如果树少于 k 层&#xff0c;则返回 -1 。 注意&#xff0c;如果两个节点与根节点的距离相同&…

能够翻译文档的免费软件-免费翻译整个文档的软件

chatgpt怎么实现批量翻译 ChatGPT是一种基于人工智能技术的自然语言处理软件&#xff0c;可以实现快速、准确的批量翻译操作&#xff0c;同时也支持多种语言翻译。下面是 ChatGPT 的批量翻译操作流程&#xff1a; 步骤 1: 确定翻译语言和翻译文本 首先需要确定要翻译的原文本…

java学习之局部内部类

目录 一、内部类简介 二、内部类的分类 三、局部内部类 第一点 第二点 第三点 第四点 第五点 第六点 第七点 一、内部类简介 类的五大成员&#xff1a;属性、方法、构造器、代码块、内部类 package com.hspedu.innerclass;public class InnerClass01 {public static…

AOP与SpringBoot使用AOP实例

AOP&#xff1a;Aspect Oriented Programming&#xff08;面向切面编程、面向方面编程&#xff09;&#xff0c;其实就是面向特定方法编程。 动态代理是面向切面编程最主流的实现。而SpringAOP是Spring框架的高级技术&#xff0c;旨在管理bean对象的过程中&#xff0c;主要通过…

Windows使用Dockers+battery historian踩坑记

1、首先&#xff0c;需要翻墙。 2、然后安装Dockers&#xff0c;网上好多博客说安装Docker Toolbox&#xff0c;我亲测无效&#xff0c;卸载后安装Docker for Windows&#xff0c;安装完成后打开&#xff0c;会提示&#xff1a; Hardware assisted virtualization and data e…

Mybatis03学习笔记

目录 使用注解开发 设置事务自动提交 mybatis运行原理 注解CRUD lombok使用&#xff08;偷懒神器&#xff0c;大神都不建议使用&#xff09; 复杂查询环境&#xff08;多对一&#xff09; 复杂查询环境&#xff08;一对多&#xff09; 动态sql环境搭建 动态sql常用标签…

大数据实战 --- 淘宝用户行为

目录 开发环境 数据描述 功能需求 数据准备 数据清洗 用户行为分析 找出有价值的用户 开发环境 HadoopHiveSparkHBase 启动Hadoop&#xff1a;start-all.sh 启动zookeeper&#xff1a;zkServer.sh start 启动Hive&#xff1a; nohup hiveserver2 1>/dev/null 2>…