尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
P2590 树的统计 题目解析
一题面一棵树上有 n 个节点编号分别为 1 到 n每个节点都有一个权值 w。我们将以下面的形式来要求你对这棵树完成一些操作I.CHANGE u t: 把结点 u 的权值改为 t。II.QMAX u v: 询问从点 u 到点 v 的路径上的节点的最大权值。III.QSUM u v: 询问从点 u 到点 v 的路径上的节点的权值和。注意从点 u 到点 v 的路径上的节点包括 u 和 v 本身。对于每个QMAX或者QSUM的操作每行输出一个整数表示要求输出的结果二理解考虑线段树结合树链剖分按照顺序梳理1输入树dfs1函数得出基本信息即 fa每个点的父节点 sz每棵子树大小 depth深度 maxson每个点的重孩子进行重链剖分2dfs2划分重链1得出3个新基本信息即 top每个点所在链的链头 dfn每个点的dfs序 fn每个dfs序所对应的点的编号2分链 重孩子的链头自己链头 轻孩子单开一条链3对dfs序构建线段树 dfs序通用性质把树压成一维数组同一条重链上所有节点的dfn编号是一段连续区间 可以把树上路径转成线段树区间任意两点路径能够拆成多段连续区间 所以可以使用线段树维护树上路径其中pushupbuild普通对于线段树查询的query和update均为模板代码4对于链查询的query_chain 求LCA模板代码如下 其中跳链步骤与之相同int LCA(int x,int y) { while(top[x]!top[y]) { if(depth[top[x]]depth[top[y]]) swap(x,y); xfa[top[x]]; } if(depth[x]depth[y]) return x; else return y; }借助条链把 x 到 y 的树上路径拆成若干条完整重链 最后同链的一段三代码详细解析在注释#includebits/stdc.h #define ll long long using namespace std; const int N3e45; int a[N],fn[N],fa[N],sz[N],depth[N],dfn[N],top[N],maxson[N],tot,ans,n,q; struct node { int L,R,maxx,sum; } st[N2]; vectorint g[N]; void pushup(int root) { st[root].maxxmax(st[root1].maxx,st[root1|1].maxx); st[root].sumst[root1].sumst[root1|1].sum; } void build(int root,int L,int R) { st[root].LL; st[root].RR; if(LR) { st[root].maxxst[root].suma[fn[L]];//注意对dfs序打线段树要反映射回编号 return ; } int midLR1; build(root1,L,mid); build(root1|1,mid1,R); pushup(root); } void update(int root,int L,int R,int k,int val) { if(LR) { st[root].maxxst[root].sumval; return ; } int midLR1; if(kmid) update(root1,L,mid,k,val); else update(root1|1,mid1,R,k,val); pushup(root); } void dfs1(int u,int f) {//作用求重儿子、sz、depth、fa fa[u]f,sz[u]1,depth[u]depth[f]1; for(int v:g[u]) { if(vf) continue; dfs1(v,u); sz[u]sz[v]; if(!maxson[u]||sz[maxson[u]]sz[v]) { //v是否是u的重孩子 maxson[u]v; } } } void dfs2(int u,int t){//作用划分重链 t即为此时u点对应的链头 top[u]t; dfn[u]tot; fn[tot]u;//反映射标记dfs序对应的编号 if(maxson[u]){//有重孩子优先走重孩子 dfs2(maxson[u],t);//链头不变重孩子自动成链 for(int v:g[u]){ if(v!maxson[u]v!fa[u]){//是轻孩子不重走 dfs2(v,v);//轻孩子单开链链头是自己 } } } } int query(int root,int L,int R,int l,int r,int type){ if(type1){ if(lLRr){ return st[root].maxx; } int midLR1; if(rmid) return query(root1,L,mid,l,r,type); else if(lmid) return query(root1|1,mid1,R,l,r,type); else return max(query(root1,L,mid,l,r,type),query(root1|1,mid1,R,l,r,type)); } else{ if(lLRr){ return st[root].sum; } int midLR1; if(rmid) return query(root1,L,mid,l,r,type); else if(lmid) return query(root1|1,mid1,R,l,r,type); else return query(root1,L,mid,l,r,type)query(root1|1,mid1,R,l,r,type); } } int query_chain(int x,int y,int type) { if(type1) ans-0x3f3f3f3f; else ans0; while(top[x]!top[y]) { if(depth[top[x]]depth[top[y]]) swap(x,y); int tmpquery(1,1,n,dfn[top[x]],dfn[x],type);//路径的一部分 if(type1) ansmax(ans,tmp); else anstmp; xfa[top[x]];//跳到不同的链直到共链 } if(depth[x]depth[y]) swap(x,y); int tmpquery(1,1,n,dfn[y],dfn[x],type);//对dfs序打线段树此时跳完后的x和y共链,这是最后的那部分路径 if(type1) ansmax(ans,tmp); else anstmp; return ans; } int main() { scanf(%d,n); for(int i1; in; i){ int aa,bb; scanf(%d%d,aa,bb); g[aa].push_back(bb); g[bb].push_back(aa); } for(int i1;in;i) scanf(%d,a[i]); dfs1(1,0); dfs2(1,1);//1的链头是自己 build(1,1,n); scanf(%d,q); while(q--){ char op[10]; int x,y; scanf(%s%d%d,op,x,y); if(op[0]C){ update(1,1,n,dfn[x],y);//对dfs序打的线段树所以找的是dfn[x] } else{ if(op[1]M){ printf(%d\n,query_chain(x,y,1)); } else{ printf(%d\n,query_chain(x,y,0)); } } } }好久没干这活了大肘子欢迎指正
RELATED

相关推荐

AI艺术生成器技术解析:从扩散模型到提示词工程实战指南

AI艺术生成器技术解析:从扩散模型到提示词工程实战指南

1. 从像素到诗意:AI艺术生成器的进化之路几年前,当人们谈论“AI艺术”时,脑海里浮现的可能是那些模糊、扭曲、带有明显算法痕迹的怪异图像。但今天,情况已经截然不同。你或许已经见过那些足以媲美专业画师、摄影师的AI作品&#x…

📅 2026/9/11 18:01:01
Java 17 + JUnit 5 黑盒测试实战:三角形问题决策表从16条到8条的化简逻辑

Java 17 + JUnit 5 黑盒测试实战:三角形问题决策表从16条到8条的化简逻辑

Java 17 JUnit 5 黑盒测试实战:三角形问题决策表从16条到8条的化简逻辑在软件测试领域,决策表是一种强大的黑盒测试技术,特别适合处理多条件组合的场景。本文将以经典的三角形判断问题为例,深入剖析如何将初始的16条规则化简为8条…

📅 2026/9/14 13:24:13
2026年建站工具对比:谁更懂“零门槛建站”?

2026年建站工具对比:谁更懂“零门槛建站”?

为什么说你的第一个网站不该将就? 面对琳琅满目的SaaS建站工具,很多初次建站的用户陷入选择困境:看似都能“拖拽建站”,但实际用起来却发现模板僵化、功能缺失、隐藏收费频出。为帮大家避开这些坑,我们对凡科建站、盈…

📅 2026/9/2 17:22:37
MORE NEWS

更多资讯

📰

AI Agent 智能体实战:任务拆解、工具调用与结果校验闭环

做后端和数据处理的朋友最近大概率都遇到过这样的场景:手里有个 AI 对话工具,问它几个问题觉得挺顺手,于是想让它帮忙把一批文档整理成一份汇总报告,结果任务丢进去,返回的要么是泛泛而谈的套话,要么是看似…

📰

WinDbg(x86)蓝屏日志分析实战:从符号配置到驱动定位

简介:WinDbg(x86)是微软官方调试工具集中面向32位Windows系统的版本,主要服务于需要分析蓝屏内存转储文件、排查驱动与应用程序崩溃的开发者及系统管理员。资源围绕蓝屏日志查看这一核心场景,提供从加载dump文件到解读错误代码、停止消息及崩…

📰

GaussDB 5.0轻量级安装包Linux部署指南:从环境核对到参数调优

简介:面向Linux环境下希望快速部署华为GaussDB数据库的开发者与运维人员,这份资源提供openGauss-Lite 5.0.0轻量级安装包,适合资源有限但需要完整数据库特性的小型环境与测试场景。压缩包共13个文件、约22.14MB,以6个sh脚本为主&a…

📰

本地AI项目从0到1部署跑通:环境自检、接口验证与批量任务实操清单

拿到一个新的开源 AI 项目,很多人第一反应是先把仓库克隆下来,然后照着 README 一路pip install。结果往往卡在第三步:依赖装完了,模型没下全;模型下全了,显存不够;显存够了,端口又被…

📰

Mycat 1.6.7.1 CentOS 7 分库分表实战指南

简介:本资源为Mycat分布式数据库中间件在CentOS 7环境下的开箱即用部署包,面向Java后端开发、DBA及分布式系统架构学习者,解决MySQL单库性能瓶颈与水平扩展难题。压缩包包含95个文件,主体为42个核心jar包(含Mycat-serv…

📰

Linux网桥brctl实战:编译、STP调参与iproute2迁移

简介:围绕 Linux 桥接控制工具 brctl 的源码资源包,面向网络运维、系统管理与虚拟化实验学习者,用于理解并实践网桥创建、端口管理、STP 与 VLAN 等桥接配置能力。压缩包共 47 个文件、约 157KB,以 8 个 C 源文件和 3 个头文件为核…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬