题解:AT_abc294_g [ABC294G] Distance Queries on a Tree

news/2024/12/22 16:30:13/文章来源:https://www.cnblogs.com/ezhe/p/18622238

题目链接

https://www.luogu.com.cn/problem/AT_abc294_g

分析

先不考虑修改。

\(dist_i\) 表示从根节点到第 \(i\) 号节点的距离,\(\operatorname{lca(u,v)}\) 表示树上两点 \(u,v\) 的最近公共祖先,那么 \(u,v\) 两点间的距离就是 \((dist_{\operatorname{lca(u,v)}}-dist_u)+(dist_{\operatorname{lca(u,v)}}-dist_v)\),即 \(dist_u+dist_v-dist_{\operatorname{lca(u,v)}}\times 2\)

对于修改操作,考虑使用 dfs 序。

\(in_i\) 表示节点 \(i\) 入栈的时间戳,\(out_i\) 表示节点 \(i\) 出栈的时间戳,那么节点 \(i\) 的子树在新的线性序列上对应的区间就是 \([in_i,out_i]\)

对于一条要被修改的边,设 \(x_1\) 表示原来的权值,\(x_2\) 表示修改后的权值,\(son\) 表示这条边上远离根节点的端点,那么就可以将新的线性序列上的区间 \([in_{son},out_{son}]\) 都作 \(-x_1+x_2\) 的操作,即对节点 \(son\) 的子树上的每一个点到根节点的距离,都 \(-x_1\)(消除原来边的影响)在 \(+x_2\)(加上新边的权值)。

可以使用差分 + 树状数组快速实现对序列的区间修改。

本题中距离最多可达到 \(2 \times 10^{14}\),需要开 long long

细节内容见代码注释。

Code

#include<bits/stdc++.h>
#define i64 long long
#define min(x,y) ((x)<(y)?(x):(y))
using namespace std;const int N=2e5;
int n,q;int tot_edge,hd[N+5];
struct Edge{int frm,to;i64 val;int lst;}g[N*2+5];
void add_edge(int u,int v,i64 w){g[++tot_edge]=Edge{u,v,w,hd[u]};hd[u]=tot_edge;
}int tim,inn[N+5],outt[N+5];
int dep[N+5],f[N+5][30];
//dfs 序 + LCA 预处理 
void dfs(int x,int fa){inn[x]=++tim;dep[x]=dep[fa]+1,f[x][0]=fa;for(int i=1;i<=25;++i)f[x][i]=f[f[x][i-1]][i-1];for(int i=hd[x];~i;i=g[i].lst)if(g[i].to^fa)dfs(g[i].to,x);outt[x]=tim;return;
}//倍增求 LCA 
int Lca(int x,int y){if(dep[x]<dep[y])x^=y,y^=x,x^=y;for(int i=25;~i;--i)if(dep[f[x][i]]>=dep[y])x=f[x][i];if(x==y)return x;for(int i=25;~i;--i)if(f[x][i]^f[y][i])x=f[x][i],y=f[y][i];return f[x][0];
}//树状数组 
i64 tr[N+5];
int lowbit(int x){return x&-x;}
void upd(int x,i64 v){for(int i=x;i<=n;i+=lowbit(i))tr[i]+=v;return;
}
i64 ask(int x){i64 res=0;for(int i=x;i;i-=lowbit(i))res+=tr[i];return res;
}int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);memset(hd,-1,sizeof hd);int op,x1,x2,x3;cin>>n;for(int i=1;i<n;++i){cin>>x1>>x2>>x3;add_edge(x1,x2,x3),add_edge(x2,x1,x3);}dfs(1,0);//预处理每个点到根节点的距离 for(int i=1;i<=tot_edge;i+=2){x1=g[i].frm,x2=g[i].to;//寻找远离根节点的端点 if(dep[x1]<dep[x2])//相当于 swap(x1,x2) x1^=x2,x2^=x1,x1^=x2;//将子树上每一个点到根节点的距离都加上这条边的权值 upd(inn[x1],g[i].val),upd(outt[x1]+1,-g[i].val);}cin>>q;while(q--){cin>>op>>x1>>x2;//修改 if(op==1){x1*=2;//链式前向星存的是双向边,应将编号 *2 int u=g[x1].frm,v=g[x1].to;//找到远离根节点的端点 if(dep[u]<dep[v])u^=v,v^=u,u^=v;//消除原边影响 upd(inn[u],-g[x1].val),upd(outt[u]+1,g[x1].val);//加上新边权值 upd(inn[u],x2),upd(outt[u]+1,-x2);g[x1].val=x2;}//查询 else{x3=Lca(x1,x2);cout<<ask(inn[x1])+ask(inn[x2])-ask(inn[x3])*2<<'\n';}}return 0;
}

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

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

相关文章

我用cursor, 半就开发了一个手机壁纸小程序,真的太强了

我用cursor, 半就开发了一个手机壁纸小程序,真的太强了。原来一周的工作量,半天搞定。体验可以微信搜索《程序员博博》同名。前言 我用chatGPT帮我写后端爬虫,分析知乎html代码,爬取知乎壁纸。然后用cursor AI工具,完全使我一个不懂前端uniapp框架的人,开发了一个小程序手…

投票:你愿意为了gxyz的图标捐献token吗?

投票:你愿意为了gxyz的图标捐献token吗?(点击选项进行投票): 愿意,请把token发给洛谷上的Leo2126 不愿意,但不愿意加入铁一 不愿意,要去铁一 蒟蒻的每一天

存储引擎整理

// 数据库的结构 // 连接层,服务层,引擎层,存储层 //创建表时,指定存储引擎 // create table name ( // ... // )engine = 存储引擎; // 查看当前数据库支持的存储引擎 // show engines; // ---------------------------------------------------------------------------…

引用 | 如何将正文引用批量设置上标?

本方法适用对象: 请注意,本方法针对下图所示论文引用格式: ①外部:半角中括号 ②内部:数字,数字与半角逗号的组合,数字与连接符号的组合,数字、半角逗号与连接符号的组合主要步骤: 1. 打开高级查找2. 在查找内容中输入\[[0-9,-]{1,}\],并勾选搜索选项中的“使用通配符…

2024秋季学期 人工智能导论期末复习笔记

2024秋季学期(二秋)人工智能导论期末复习笔记Chapter3 知识推理Chapter4 不确定推理Chapter5-1 机器学习Chapter5-2 深度学习Chapter5-3 强化学习

鸿蒙开发实战:揭秘页面与项目生命周期,实现精准监控

前言 在鸿蒙应用开发中,每一个页面和组件都承载着特定的生命周期。这些生命周期阶段,如同生命的轨迹,记录着页面从诞生到消亡的每一个重要时刻。深入理解和监控这些生命周期,不仅能提升应用性能,还能帮助我们更好地把握用户体验。 1. 鸿蒙@Component组件生命周期详解 在鸿…

2024-2025-1 20241318M《计算机基础与程序设计》第十三周学习总结

作业信息这个作业属于哪个课程 https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP这个作业要求在哪里 https://www.cnblogs.com/rocedu/p/9577842.html#WEEK13这个作业的目标 <自学教材《C语言程序设计》第12章并完成云班课测试>| |作业正文|https://i.cnblogs.com…

基于HarmonyOS 5.0 (Next)的一种面向多设备跨平台的高性能自适应布局能力研究和实现

引言 随着万物互联时代的到来,操作系统作为连接设备、应用与用户体验的核心,其重要性日益凸显。华为最新发布的HarmonyOS 5.0(Next)作为一款完全自主的第三大手机操作系统,不仅实现了全栈自研,更在技术架构和生态体验上实现了颠覆性升级。HarmonyOS 5.0(Next)通过全新的…

2024-2025-1 20241319 《计算机基础与程序设计》第十三周学习总结

作业信息这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计这个作业要求在哪里 https://www.cnblogs.com/rocedu/p/9577842.html#WEEK13这个作业的目标 《C语言程序设计》第12章作业正文 https://www.cnblogs.com/wchxx/p/18622144**教材学习内容总结 结构体(struct) 1…

【原创】xenomai环境下开源实时数控系统LinuxCNC编译安装

LinuxCNC是一款基于Linux操作系统的开源实时数控系统,可将普通计算机转变为高效的CNC(计算机数字控制)机器,本文记录xenomai下linuxcnc的构建安装。linuxcnc 在xenomai下的构建简单记录,参考链接https://www.linuxcnc.org/docs/devel/html/code/building-linuxcnc.html 1.…

2024-2025-1 20241301 《计算机基础与程序设计》第十三周学习总结

|这个作业属于哪个课程|2024-2025-1-计算机基础与程序设计| |这个作业要求在哪里|2024-2025-1计算机基础与程序设计第一周作业| |这个作业的目标|<复习知识,巩固基础>| |作业正文|https://www.cnblogs.com/HonJo/p/18622132| 一、教材学习内容 (一)网络 根据提供的搜索…

【ByPass】最新发现绕过浏览器隔离技术的攻击方法

BaizeSec 白泽安全实验室 2024年12月10日 15:26 北京 在网络安全领域,浏览器隔离技术一直被视为对抗网络钓鱼和基于浏览器的攻击的有效手段。然而,根据Mandiant的最新研究,攻击者已经找到了一种利用QR码绕过浏览器隔离的攻击方法,从而能够从远程服务器向受害设备发送恶意数…