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

题意

给定大小为 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.mzph.cn/bicheng/57780.shtml

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

相关文章

迭代器失效和支持随机访问的容器总结

创作活动 迭代器失效&#xff1a; 顺序容器&#xff08;如vector、deque、list&#xff09; vector 插入操作&#xff1a; 当在vector中间或头部插入元素时&#xff0c;所有位于插入点之后的迭代器都会失效。这是因为vector的元素在内存中是连续存储的&#xff0c;插入元素可能…

15.6 JDBC数据库编程6——可滚动和可更新的ResultSet

目录 15.6 引言 15.6.1 可滚动的ResultSet 15.6.1 可更新的ResultSet 15.6 引言 可滚动的ResultSet是指在结果集对象上不但可以向前访问结果集中的记录&#xff0c;还可以向后访问结果集中记录。可更新的ResultSet是指不但可以访问结果集中的记录&#xff0c;还可以更新…

【深度学习代码调试5】标准化数据集:TensorFlow Datasets (TFDS)自动化数据加载与预处理

【标准化数据集】TensorFlow Datasets、TFDS&#xff1a;自动化数据加载与预处理 写在最前面1. 什么是 TensorFlow Datasets (TFDS)?主要特点&#xff1a; 2. TFDS 的核心 API&#xff1a;tfds.builder 和 download_and_preparetfds.builder&#xff1a;创建数据集构建器示例&…

【大数据学习 | Zookeeper】Zookeeper的选举机制

zookeeper的选举机制分为第一次启动和非第一次启动两种情况。 1. 选举机制 - > 第一次启动 (1)服务器1启动&#xff0c;发起一次选举。服务器1投自己一票。此时服务器1票数一票&#xff0c;不够半数以上(3票)&#xff0c;选举无法完成&#xff0c;服务器1状态保持为 LOOKIN…

STM32之EC800K 4G模块驱动

1.EC800K简介 EC800K&#xff0c;特别是EC800K-CN&#xff0c;是移远通信专为M2M&#xff08;机器对机器&#xff09;和IoT&#xff08;物联网&#xff09;领域而设计的超小尺寸LTE Cat 1无线通信模块。EC800K-CN作为一款专为M2M和IoT领域设计的LTE Cat 1无线通信模块&#xff…

w~视觉~合集8

我自己的原文哦~ https://blog.51cto.com/whaosoft/12320868 #xx1 基于mxnet的训练代码迁移到pytorch上和 在yolov5的代码基础上验证了一些目标检测的想法一起发了 在迁移mxnet训练代码的时候&#xff0c;很长一段时间结果都无法对齐&#xff0c;于是我不得不又重新认真的读…

Flutter Column组件实战案例

In this section, we’ll explore the Column widget, a fundamental tool for arranging widgets vertically in Flutter. We’ll dive into its functionality and guide you through using it effectively to create well-organized and visually appealing layouts. 在本节…

UE5 第一人称示例代码阅读0 UEnhancedInputComponent

UEnhancedInputComponent使用流程 我的总结示例分析firstthenand thenfinally&代码关于键盘输入XYZ 我的总结 这个东西是一个对输入进行控制的系统&#xff0c;看了一下第一人称例子里&#xff0c;算是看明白了&#xff0c;但是感觉这东西使用起来有点绕&#xff0c;特此梳…

Ubuntu开启路由转发功能

IP转发允许系统在不同的网络接口之间路由数据包&#xff0c;这对于设置路由器等任务至关重要。下面是在Ubuntu上临时和永久启用IP转发的步骤。 1. 查看“当前IP转发状态” sysctl net.ipv4.ip_forward其中&#xff1a; ① net.ipv4.ip_forward 0 表示IP转发功能关闭 …

ctfshow(41)--RCE/命令执行漏洞--或绕过

Web41 源代码&#xff1a; if(isset($_POST[c])){$c $_POST[c]; if(!preg_match(/[0-9]|[a-z]|\^|\|\~|\$|\[|\]|\{|\}|\&|\-/i, $c)){eval("echo($c);");} }else{highlight_file(__FILE__); }代码审计&#xff1a; 过滤了数字和字母&#xff0c;但没有过滤或…

语言模型微调:提升语言Agent性能的新方向

人工智能咨询培训老师叶梓 转载标明出处 大多数语言Agent依赖于少量样本提示技术&#xff08;few-shot prompting&#xff09;和现成的语言模型。这些模型在作为Agent使用时&#xff0c;如生成动作或自我评估&#xff0c;通常表现不佳&#xff0c;且鲁棒性差。 论文《FIREACT…

随机抽取学号

idea 配置 抽学号 浏览器 提交一个100 以内的整数。&#xff0c;后端接受后&#xff0c;根据提供的整数&#xff0c;产生 100 以内的 随机数&#xff0c;返回给浏览器&#xff1f; 前端&#xff1a;提供 随机数范围 &#xff0c;病发送请求后端&#xff1a;处理随机数的产生&…

学习记录:js算法(七十四):跳跃游戏II

文章目录 跳跃游戏II思路一&#xff1a;贪心算法思路二&#xff1a;动态规划思路三&#xff1a;广度优先搜索 (BFS)思路四&#xff1a;深度优先搜索 (DFS) 跳跃游戏II 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的…

python表格处理prettytable vs pandas

prettytable和pandas简介 Python中prettyTable和pandas都是用于处理和展示数据的工具&#xff0c;但它们在设计目标、功能和使用场景上有显著的不同。 PrettyTable是一个轻量级的库&#xff0c;主要用于创建美观的ASCII表格&#xff0c;让表格数据在命令行或文本界面中看起来更…

【电机应用】变频器控制——变频水泵、变频空调

【电机应用】变频器控制——变频水泵、变频空调 文章目录 [TOC](文章目录) 前言一、变频器1、变频器的组成2、变频器的工作原理3、变频器常用算法 二、变频器的应用场景1、变频水泵2、变频空调 三、参考文献总结 前言 使用工具&#xff1a; 提示&#xff1a;以下是本篇文章正文…

QHeaderView添加复选框以及样式

实现这个效果&#xff0c;需要重写paintSection来实现效果&#xff0c;同时重写mousePressEvent来执行是否勾选复选框。 paintSection实现一些复选框样式 void CheckBoxHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const {if (m_…

Android 原生开发与Harmony原生开发浅析

Android系统 基于Linux ,架构如下 底层 (Linux )> Native ( C层) > FrameWork层 (SystemService) > 系统应用 (闹钟/日历等) 从Android发版1.0开始到现在15,经历了大大小小的变革 从Android6.0以下是个分水岭,6.0之前权限都是直接卸载Manifest中配置 6.0开始 则分普…

Matlab|基于氢储能的热电联供型微电网优化调度方法

目录 1 主要内容 模型求解流程 2 部分程序 3 程序结果 日前调度 日内调度 4 下载链接 1 主要内容 该程序复现《基于氢储能的热电联供型微电网优化调度方法》&#xff0c;针对质子交换膜燃料电池和电解槽的热电联供特性&#xff0c;为避免氢能系统的热能浪费并进一步提高…

k8s 综合项目笔记

综述 这篇笔记主要是为了记录下自己写 k8s 综合项目的过程。 由于自己之前已经写过简单的开发和运维项目&#xff0c;所以这里就结合一下&#xff0c;在搭建 k8s 集群后安装运维常用服务&#xff0c;比如 ansible 和 prometheus&#xff0c;用 NFS 实现数据存储同步&#xff0c…

Windwos下Docker下载安装centos7.6

操作步骤&#xff1a; 1.打开docker软件进入到DockerHub页面搜索contos镜像 2.在终端通过命令获取镜像并创建容器运行 docker run -itd --name test_centos7.6 centos:7.6.1810 test_centos7.6表示容器的名称 centos:7.6.1810表示镜像的名称&#xff0c;如果镜像不存在会默认拉…