当前位置: 首页 > news >正文

洛谷P4556思路分享(线段树合并,树上差分,线段树上二分)

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

题意概述

\(n\) 座房屋,构成一棵树。救济粮分 \(m\) 次发放,每次给 \(x\)\(y\) 路径上每个房屋发放一袋 \(z\) 类型的救济粮。问所有救济粮发放完之后,每座房屋数量最多的救济粮类型,如果没有,输出 \(0\)

\(1 \leq n, m \leq 10^5\)\(1 \leq z \leq 10^5\)

思路

\(x\)\(y\) 路径上所有节点分发同样的救济粮,考虑树上差分。

救济粮信息可以用值域线段树维护,最后统计答案的时候合并线段树即可。

具体的,动态开点,给每个节点建一棵值域线段树,维护该节点所有类型的救济粮中数量最大值,查询这个最大值对应的类型只需要在线段树上二分即可。

发放救济粮的过程,记 \(x\)\(y\)\(LCA\)\(t\)\(x\)\(y\) 节点的 \(z\) 类型救济粮数量 \(+1\)\(t\)\(t\) 的父节点的 \(z\) 类型救济粮数量 \(-1\)

最后向上合并线段树,计算每个节点答案即可,代码中使用了倍增求 \(LCA\)

时间复杂度 \(\mathcal{O}((n+m) \log N)\)\(N\)\(z\) 的上界。

代码

//author:kzssCCC#include <bits/stdc++.h>
using namespace std;
using ll = long long;const int N = 1e5+5; 
const int INF = 1e9;class node{
public:int left=-1,right=-1,mx=0;
};void solve(){int n,m;cin >> n >> m;vector<vector<int>> adj(n+1);for (int i=0;i<n-1;i++){int u,v;cin >> u >> v;adj[u].push_back(v);adj[v].push_back(u);}vector<int> depth(n+1),par(n+1,-1);	function<void(int)> dfs = [&](int u){for (auto& v:adj[u]){if (v==par[u]) continue;depth[v] = depth[u]+1;par[v] = u;dfs(v);}};dfs(1);vector<vector<int>> dp(n+1,vector<int>(32,-1));for (int i=1;i<=n;i++){dp[i][0] = par[i];}for (int k=1;k<32;k++){for (int i=1;i<=n;i++){if (dp[i][k-1]==-1) continue;dp[i][k] = dp[dp[i][k-1]][k-1];	}}auto getlca = [&](int u,int v){if (depth[u]<depth[v]){swap(u,v);}int diff = depth[u]-depth[v];for (int k=31;k>=0;k--){if (diff>>k&1){u = dp[u][k];}}if (u==v) return u;for (int k=31;k>=0;k--){if (dp[u][k]!=-1 && dp[v][k]!=-1 && dp[u][k]!=dp[v][k]){u = dp[u][k];v = dp[v][k];}}return par[u];};vector<node> seg{{}};vector<int> root(n+1);for (int i=1;i<=n;i++){seg.push_back({});root[i] = seg.size()-1;}	function<void(int,int,int,int,int)> update = [&](int rt,int l,int r,int pos,int val){if (l==r){seg[rt].mx += val;return;}int mid = l+r >> 1;if (pos<=mid){if (seg[rt].left==-1){seg.push_back({});seg[rt].left = seg.size()-1;}update(seg[rt].left,l,mid,pos,val);}		else{if (seg[rt].right==-1){seg.push_back({});seg[rt].right = seg.size()-1;}update(seg[rt].right,mid+1,r,pos,val);}seg[rt].mx = max(seg[rt].left!=-1?seg[seg[rt].left].mx:-INF,seg[rt].right!=-1?seg[seg[rt].right].mx:-INF);};while (m--){int x,y,z;cin >> x >> y >> z;int t = getlca(x,y);update(root[x],1,N,z,1);update(root[y],1,N,z,1);update(root[t],1,N,z,-1);if (par[t]!=-1) update(root[par[t]],1,N,z,-1);}function<int(int,int,int,int)> merge = [&](int rt1,int rt2,int l,int r){if (rt1==-1 || rt2==-1){return rt1==-1?rt2:rt1;}if (l==r){seg[rt1].mx = seg[rt1].mx+seg[rt2].mx;return rt1;}int mid = l+r >> 1;seg[rt1].left = merge(seg[rt1].left,seg[rt2].left,l,mid);seg[rt1].right = merge(seg[rt1].right,seg[rt2].right,mid+1,r);seg[rt1].mx = max(seg[rt1].left!=-1?seg[seg[rt1].left].mx:-INF,seg[rt1].right!=-1?seg[seg[rt1].right].mx:-INF);if (seg[rt1].mx==-INF){seg[rt1].mx = 0;}return rt1;};function<int(int,int,int,int)> first_valid = [&](int rt,int l,int r,int mx){if (rt==-1 || seg[rt].mx<mx){return -1;}if (l==r){return l;}int mid = l+r >> 1;int res = first_valid(seg[rt].left,l,mid,mx);if (res!=-1){return res;}return first_valid(seg[rt].right,mid+1,r,mx);};vector<int> res(n+1);function<void(int)> dfs2 = [&](int u){for (auto& v:adj[u]){if (v==par[u]) continue;dfs2(v);merge(root[u],root[v],1,N);}res[u] = seg[root[u]].mx==0?0:first_valid(root[u],1,N,seg[root[u]].mx);};dfs2(1);for (int i=1;i<=n;i++){cout << res[i] << '\n';}
}int main(){ios::sync_with_stdio(false);cin.tie(0);int t = 1;// cin >> t;while (t--) solve();return 0;
}
http://www.jsqmd.com/news/815738/

相关文章:

  • 非线智能Nonelinear怎么样?非线智能API怎么样?
  • 别再只会画柱状图了!用GraphPad Prism玩转分组数据:性别与药物效应的可视化拆解
  • TensorRT模型部署避坑:为什么你的自定义插件在推理时‘消失’了?
  • GraphRAG-SDK实战:基于知识图谱与FalkorDB构建下一代智能问答系统
  • 别再手动调UV了!用Mesh Baker 3.0一键合并Unity场景贴图(附材质球复用技巧)
  • SDL Trados Studio(软件本地化) 18.1.4
  • 携程任我行礼品卡回收的三种渠道区别! - 圆圆收
  • 在Node.js后端服务中集成Taotoken实现AI功能的最佳实践
  • 崩坏星穹铁道模拟宇宙自动化终极指南:解放双手的完整教程
  • 广药白云山星群是什么来头?一文讲清 - 新闻观察者
  • 一键解锁小米智能家居:hass-xiaomi-miot让HomeAssistant轻松掌控你的米家设备
  • 别再手动调参了!用Matlab linprog函数优化你的机器学习模型超参数(附R2023b实例)
  • 题解:luogu P4775([NOI2018] 情报中心)
  • 海外发票智能解析:跨版式、多税制票据的自动化处理方案(附GitHub项目地址)
  • 环境配置与基础教程:学习率调度器深度对比:Cosine、Warmup、MultiStep 在 YOLO 训练中的选型策略
  • 从零到一:51单片机驱动NRF24L01实现点对点无线通信全解析
  • Office PPT 批量删除每页相同位置的内容(图片文字等)
  • 2026贵州化妆学校权威推荐榜:正规靠谱机构大盘点,零基础必看 - 深度智识库
  • AI智能体Hermes Agent:闭环学习与多平台部署实战指南
  • 如何在 MATLAB 中调用 OpenAI 兼容 API 连接 Taotoken 多模型服务
  • AnuPpuccin:为Obsidian用户重新定义笔记美学的设计哲学
  • 告别编译焦虑:手把手教你用Buildroot为全志V3S定制最小根文件系统
  • 2026无锡卫生间免砸砖防水、外墙、地下室、楼顶渗漏+彩钢瓦、阳光房隔热 本地专业防水公司TOP5权威推荐(2026年5月本地最新深度调研) - 企业资讯
  • 手把手教你用宝塔面板,30分钟搞定Moodle在线学习平台部署(含SSL配置与数据库避坑)
  • 盒马鲜生卡回收:快速变现攻略及常见问题全解 - 团团收购物卡回收
  • Dify连接器实战:打通AI应用与业务系统的最后一公里
  • 沈阳雨露恒远客运:康平旅游包车怎么联系 - LYL仔仔
  • 太原GEO推广服务核心优势 帮企业打通AI获客新路径 - 奔跑123
  • 2026杭州婚纱照优选|避开132家坑,这9家闭眼选不踩雷 - 江湖评测
  • TQVaultAE深度解析:告别《泰坦之旅》仓库管理烦恼的终极方案