【lca,树上差分】P3128 [USACO15DEC] Max Flow P

news2024/10/25 3:42:29

题意

给定大小为 n ( 2 ≤ n ≤ 5 × 1 0 4 ) n(2 \leq n \leq 5 \times 10^4) n(2n5×104) 的树,并给定 m ( 1 ≤ m ≤ 1 0 5 ) m(1 \leq m \leq 10^5) m(1m105) 条树上的路径(给定两个端点,容易证明两个点树上路径唯一),求上述路径中最多有几条路径同时经过一个点。

【样例输入】

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
在这里插入图片描述

思路

在这里插入图片描述

考虑树上差分。树上差分,顾名思义,就是在树上进行类似差分的操作。

假设有一条 6 ← 4 6 \gets 4 64 的路径。

如果要暴力标记,则单次复杂度最坏情况下近似于 O ( n ) O(n) O(n),时间爆炸。

但是,如果我们把原路径看作 6 ← 1 + 1 ← 5 6 \gets 1 + 1 \gets 5 61+15 两条路径的和的话,我们就会有一些发现:

对于(更改后)路径上每一个点,我们只需要标记头尾,就可以在树上形成类似差分的东西。

考虑如何差分,记差分数组为 c h a f e n chafen chafen c h a f e n i chafen_i chafeni 表示第 i i i 个点及其所有祖先的路径数量之和中经过节点 i i i 的那一部分,要标记一条由 i i i j j j 的路径。

c h a f e n x ← c h a f e n x + 1 , c h a f e n y ← c h a f e n y + 1 , c h a f e n l c a ( x , y ) ← c h a f e n l c a ( x , y ) − 1 , c h a f e n f a l c a ( x , y ) ← c h a f e n f a l c a ( x , y ) − 1 chafen_x \gets chafen_x + 1,chafen_y \gets chafen_y + 1,chafen_{lca(x,y)} \gets chafen_{lca(x,y)} - 1,chafen_{fa_{lca(x,y)}} \gets chafen_{fa_{lca(x,y)}} - 1 chafenxchafenx+1,chafenychafeny+1,chafenlca(x,y)chafenlca(x,y)1,chafenfalca(x,y)chafenfalca(x,y)1

拿上图中 6 ← 4 6 \gets 4 64 举例,可以发现 l c a ( 4 , 6 ) = 1 lca(4,6) = 1 lca(4,6)=1

我们标记 c h a f e n 6 , c h a f e n 4 chafen_6,chafen_4 chafen6,chafen4 加上 1 1 1,可以发现 c h a f e n 1 chafen_1 chafen1 作为两者共同祖先,加了两次,故要扣掉。

因为两个的路径不包括他们最近共同祖先的祖先,所以 c h a f e n f a l c a ( x , y ) chafen_{fa_{lca(x,y)}} chafenfalca(x,y) 也要减一。

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
int head[50005],nex[100005],to[100005],cnt = 0;
int deep[50005],max_deep;
int d[50005][25];

int chafen[50005];
void add(int x,int y) {
	nex[++cnt] = head[x];
	head[x] = cnt;
	to[cnt] = y;
}
void find_deep(int now,int fa) {
	if(now != fa)d[now][0] = fa;
	for(int i = head[now];i;i = nex[i]) {
		if(to[i] != fa) {
			deep[to[i]] = deep[now] + 1;
			find_deep(to[i],now); 
		}
	}
	max_deep = max(max_deep,deep[now]);
	return;
}
void jump1(int &x,int &y) {
	int del_deep = deep[x] - deep[y];
	int r = 0;
	while(del_deep) {
		if(del_deep & 1) {
			x = d[x][r];
		}
		r++;
		del_deep >>= 1;
	}
	return;
}
int jump(int x,int y) {
	int r = 0;
	while((1 << r) <= deep[x]) r++;
	r--;
	for(;r >= 0;r--) {
		if(d[x][r] != d[y][r]) {
			x = d[x][r];
			y = d[y][r];
		}
	}
	if(x == y) return x;
	else return d[x][0];
}
int ans = -1e18;
int lca(int x,int y) {
	if(deep[y] > deep[x]) swap(x,y);
	if(deep[x] != deep[y]) jump1(x,y);
	if(x == y) return x;
	return jump(x,y);
}
void dfs(int now,int fa) {
	for(int i = head[now];i;i = nex[i]) {
		if(to[i] != fa) dfs(to[i],now),chafen[now] += chafen[to[i]];
	}
	ans = max(ans,chafen[now]);
	//printf("%lld %lld\n",now,chafen[now]);
	return;
}
signed main() {
	scanf("%lld %lld",&n,&m);
	for(int i = 1;i < n;i++) {
		int x,y;
		scanf("%lld %lld",&x,&y);
		add(x,y),add(y,x);
	} 
	find_deep(1,1);
	for(int i = 1;(1 << i) <= max_deep;i++) {
		for(int j = 1;j <= n;j++) {
			if(deep[j] < (1 << i)) continue;
			d[j][i] = d[d[j][i - 1]][i - 1];
		}
	}
	for(int i = 1;i <= m;i++) {
		int x,y;
		scanf("%lld %lld",&x,&y);
		int z = lca(x,y);
		chafen[x]++,chafen[y]++,chafen[z]--,chafen[d[z][0]]--;
	}
	dfs(1,1);
	printf("%lld\n",ans);
	return 0;
}

AC记录

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分布式-单元化架构1

一 两地三中心 1.1 两地三中心* 两地指的是两个城市&#xff1a;同城&#xff0c;异地。三中心指的是三个数据中心&#xff1a;生产中心、同城容灾中心、异地容灾中心。 在同一个城市或者临近的城市建设两个相同的系统&#xff0c;双中心具备相当的业务处理能力&#xff0c;…

【MySQL】索引的机制、使用

在学习索引知识之前&#xff0c;我们可以先了解一下什么是索引。实际上&#xff0c;索引就是数据库中一个或多个列存储的结构&#xff0c;能够支持数据库管理系统在不扫描整张表的情况下也能查询到数据行&#xff0c;能够大大提升查询效率。举个例子&#xff0c;我们想要找到一…

技术成神之路:设计模式(二十二)命令模式

相关文章&#xff1a;技术成神之路&#xff1a;二十三种设计模式(导航页) 介绍 命令模式&#xff08;Command Pattern&#xff09;是一种行为设计模式&#xff0c;允许将请求&#xff08;命令&#xff09;封装为对象&#xff0c;从而使您可以使用不同的请求、队列或记录请求日…

硬件基础知识补全计划【一】电阻

一、电阻理论 1.1 电流定义 电流&#xff1a;电流的强弱用电流强度来描述&#xff0c;电流强度是单位时间内通过导体某一横截面的电荷量&#xff0c;简称电流&#xff0c;用I表示。1 秒内有 6.241509310^18 个元电荷通过横截面的电流&#xff0c;定义为 1 安 (A)。 电压&…

【C++】在Windows中使用Boost库——实现TCP、UDP通信

目录 一、编译Boost库 二、TCP服务端 三、TCP客户端 四、UDP连接 一、编译Boost库 1. 先去官网下载Boost库源码 2. 点击下载最新的版本 下载Windows环境的压缩包&#xff0c;然后解压 3. 在解压后的目录路径下找到“bootstrap.bat” 打开控制台&#xff0c;在“bootstrap.…

Linux LCD 驱动实验

LCD 是很常用的一个外设&#xff0c;在裸机篇中我们讲解了如何编写 LCD 裸机驱动&#xff0c;在 Linux 下LCD 的使用更加广泛&#xff0c;再搭配 QT 这样的 GUI 库下可以制作出非常精美的 UI 界面。本章我们就来学习一下如何在 Linux 下驱动 LCD 屏幕。 Framebuffer 设备 先来…

ShardingSphere 分库分表入门实战

分库分表 需求分析 如果我们的平台发展迅速&#xff0c;用户量激增&#xff0c;从数据库层面去思考&#xff0c;哪个表的数据会最大呢&#xff1f; 回顾一下我们的数据库设计&#xff1a; 1&#xff09;app 应用表 显然不会&#xff0c;成百上千的应用已经多&#xff0c;但…

ESP32移植Openharmony设备开发---(6)Mutex互斥锁

Mutex互斥锁 官方文档&#xff1a;OpenAtom OpenHarmony 基本概念 互斥锁又称互斥型信号量&#xff0c;用于实现对共享资源的独占式处理。当有任务持有时&#xff0c;这个任务获得该互斥锁的所有权。当该任务释放它时&#xff0c;任务失去该互斥锁的所有权。当一个任务持有互…

2024年最新苹果iOS证书申请创建App详细图文流程

iOS 证书设置指南&#xff1a; 对于开发者来说&#xff0c;在没有Mac电脑或对Xcode等开发工具不熟悉的情况下&#xff0c;如何快速完成IOS证书制作和IPA文件提交至开发者中心一直是一个难题。但是现在&#xff0c;有了初雪云提供的极简工具&#xff0c;您可以轻松实现这两个任…

Appium中的api(一)

目录 1.基础python代码准备 1--参数的一些说明 2--python内所要编写的代码 解释 2.如何获取包名和界面名 1-api 2-完整代码 代码解释 3.如何关闭驱动连接 4.安装卸载app 1--卸载 2--安装 5.判断app是否安装 6.将应用放到后台在切换为前台的时间 7.UIAutomatorViewer的使用 1--找…

git rebase的常用场景: 交互式变基, 变基和本地分支基于远端分支的变基

文章目录 作用应用场景场景一&#xff1a;交互式变基(合并同一条线上的提交记录) —— git rebase -i HEAD~2场景二&#xff1a;变基(合并分支) —— git rebase [其他分支名称]场景三&#xff1a;本地分支与远端分支的变基 作用 使git的提交记录变得更加简洁 应用场景 场景…

【华为HCIP实战课程十六】OSPF虚链路Vlink,网络工程师

一、vlink续 区域内部的路由优于区域之间的路由,区域之间优于外部路由,外部路由类型1优于外部类型2 只有同一级别的路由才会对比cost <R3>tracert 11.1.1.1 traceroute to 11.1.1.1(11.1.1.1), max hops: 30 ,packet length: 40,press CTRL_C to break 1 10.1.35.5 …

Wave-Mamba 论文总结

题目&#xff1a;Exchange&#xff08;交换&#xff09; Wave-Mamba: Wavelet State Space Model&#xff08;小波状态空间模型&#xff09;for Ultra-High-Definition&#xff08;超高清&#xff09;Low-Light Image Enhancement&#xff08;弱光图像增强&#xff09; 论文&am…

stm32单片机基于rt-thread 的 串行 Flash 通用驱动库 SFUD 的使用

1024程序员节&#xff5c;征文 一、sfud 通用驱动库介绍 SFUD 是一款开源的串行 SPI Flash 通用驱动库。由于现有市面的串行 Flash 种类居多&#xff0c;各个 Flash 的规格及命令存在差异&#xff0c; SFUD 就是为了解决这些 Flash 的差异现状而设计&#xff0c;能够支持不同品…

二叉树习题其一Java【力扣】【算法学习day.8】

前言 书接上篇文章介绍的链表基础知识—>二叉树理论&#xff0c;这篇文章我们将通过习题来掌握哈希表的使用。 ###我做这类文档一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会…

PHP多功能图片编辑器

PHP多功能图片编辑器 前言效果图功能说明平台支持情况部分源码领取源码下期更新 前言 PHP多功能图片编辑器 工具箱网站源码无需数据库上传即用&#xff0c;测试了一下还可以&#xff0c;免费分享自行研究。 效果图 功能说明 ✓ 无需上传&#xff0c;使用浏览器自身进行转换 …

049_python基于Python的热门微博数据可视化分析

目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍&#xff1a;CodeMentor毕业设计领航者、全网关注者30W群落&#xff0c;InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者&#xff0c;博客领航之星、开发者头条/腾讯云/AW…

多模态大语言模型(MLLM)-Deepseek Janus

论文链接&#xff1a;https://arxiv.org/abs/2410.13848 代码链接&#xff1a;https://github.com/deepseek-ai/Janus 本次解读Janus: Decoupling Visual Encoding for Unified Multimodal Understanding and Generation 前言 Deepseek出品&#xff0c;必属精品。 创新点 传…

如何在Java应用中发送短信

很多业务场景里&#xff0c;我们都需要发送短信&#xff0c;比如登陆验证码、告警、营销通知、节日祝福等等。 这篇文章&#xff0c;我们聊聊 Java 应用中如何优雅的发送短信。 1 客户端/服务端两种模式 Java 应用中发送短信通常需要使用短信服务提供商提供的短信 API 。 我…

多ip访问多网站

多IP访问多网站 1.预配操作 [rootlocalhost ~]# mount /dev/sr0 /mnt mount: /mnt: WARNING: source write-protected, mounted read-only. [rootlocalhost ~]# systemctl stop firewalld ----------关闭防火墙 [rootlocalhost ~]# setenforce 0 -------关闭selinux2.安装n…