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

P1600 [NOIP 2016 提高组] 天天爱跑步 分析

题目概述

题目链接:https://www.luogu.com.cn/problem/P1600。

给你一棵树,每个节点上有一个观察时间,现在有 \(m\) 个选手,选手会以每秒一个节点的速度,从 \(s_i\)\(t_i\)

求对于每个节点的观察时间能观察到多少个选手。

分析

经典题目记录一下。

显然,从 \(s_i\)\(t_i\),可以拆成 \(s_i\rightarrow lca\) 以及 \(lca\rightarrow t_i\)

于是我们分两类进行讨论。

左半部分(\(s_i\rightarrow lca\)

那么第 \(i\) 个选手能在节点 \(u\) 被观察到当且仅当:\(dep_{s_i}-dep_{u}=w_u\)

把相同下标的放一起有:\(dep_{s_i}=w_u+dep_u\)

也就是说在这条路径上面每个点需要查询自己能不能满足 \(dep_u+w_u=dep_{s_i}\),相当于我可以放 \(dep_{s_i}\) 到这个点上作为我要求的答案,这种方法在 dsu on tree 很常见。

右半部分(\(t_i\rightarrow lca\)

在节点 \(u\) 能够被观察到当且仅当:\(dep_{s_i}+dep_u-2\times dep_{lca}=w_u\)

移项可得:\(w_u-dep_u=dep_{s_i}-2\times dep_{lca}\)

结合

用两个桶存即可,只需要遍历子树,所以说直接差分。

代码

时间复杂度 \(\mathcal{O}(n+m)\)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#define int long long
#define N 300005
#define PII pair<int,int>
using namespace std;
const int D = 3e5;
int fa[N][30],dep[N];
vector<int> g[N];
vector<PII> add[N],del[N];
int cnt[2][N << 1];
void dfs0(int cur,int father) {fa[cur][0] = father;dep[cur] = dep[father] + 1;for (auto i : g[cur])if (i != father) dfs0(i,cur);
}
int LCA(int x,int y) {if (x == y) return x;if (dep[x] < dep[y]) x ^= y ^= x ^= y;for (int j = 25;j >= 0;j --)if (dep[fa[x][j]] >= dep[y]) x = fa[x][j];if (x == y) return x;for (int j = 25;j >= 0;j --)if (fa[x][j] != fa[y][j]) x = fa[x][j],y = fa[y][j];return fa[x][0];
}
int n,m,w[N],ans[N];
void dfs(int cur,int fa) {int pre1 = cnt[0][w[cur] + dep[cur] + D],pre2 = cnt[1] [w[cur] - dep[cur] + D];for (auto i : add[cur]) cnt[i.first][i.second + D] ++;for (auto i : del[cur]) cnt[i.first][i.second + D] --;for (auto i : g[cur])if (i != fa) dfs(i,cur);ans[cur] = cnt[0][w[cur] + dep[cur] + D] - pre1 + cnt[1][w[cur] - dep[cur] + D] - pre2;
}
signed main(){cin >> n >> m;for (int i = 1;i < n;i ++) {int u,v;scanf("%lld%lld",&u,&v);g[u].push_back(v);g[v].push_back(u);}for (int i = 1;i <= n;i ++) scanf("%lld",&w[i]);dfs0(1,0);for (int j = 1;j <= 25;j ++)for (int i = 1;i <= n;i ++)fa[i][j] = fa[fa[i][j - 1]][j - 1];for (int i = 1;i <= m;i ++) {int st,ed;scanf("%lld%lld",&st,&ed);int t = LCA(st,ed);add[st].push_back({0,dep[st]}),del[fa[t][0]].push_back({0,dep[st]});add[ed].push_back({1,dep[st] - 2 * dep[t]}),del[t].push_back({1,dep[st] - 2 * dep[t]});}dfs(1,0);for (int i = 1;i <= n;i ++) cout << ans[i] << ' ';return 0;
}
http://www.zskr.cn/news/28890.html

相关文章:

  • 2025年10月色斑淡化产品对比榜:五款精华通路机制深度解析
  • 题解:P4204 [NOI2006] 神奇口袋
  • SQL - 递归查询父节点
  • 2025年精密弹簧厂家权威推荐榜单:压缩弹簧、拉伸弹簧、扭转弹簧、异形弹簧专业制造商综合评测与选购指南
  • SQL Server 报错引用了无效的表`表名`
  • 2025年冲压件厂家推荐排行榜,新能源冲压件,光伏冲压件,精密冲压件,异形冲压件,五金冲压件,铝冲压件,汽配冲压件,不锈钢冲压件,家具冲压件公司推荐
  • 2025年电源适配器厂家权威推荐榜单:开关电源适配器,笔记本电源适配器,手机电源适配器,工业电源适配器公司精选
  • 2025年环保空调厂家权威推荐榜:移动式环保空调,节能环保空调,工业环保空调源头厂家综合解析与选购指南
  • CSP-S模拟37(全真 1)
  • 2025年10月产后孕斑修复产品推荐榜:权威对比与选购指南
  • 2025年10月油烟机品牌对比榜:海信技术领跑五强评价
  • 2025年10月敏感肌产品推荐榜:温和美白面霜对比排行
  • 特斯拉电池坏了只能去他的4S店维修!破解者被判刑
  • PHP 异常处理全攻略 Try-Catch 从入门到精通完全指南
  • 状态最短路
  • 2025 CSP 赛前复习笔记
  • Borland Turbo products
  • 港科语义地图-低带宽场景下的多机器人地图对齐与共享定位提供了通用基石 - MKT
  • 港科轻量化地图 - MKT
  • PandaCoder:致敬MyBatis Log Plugin,但我们做得更极致!
  • Python---学习
  • [DOS] Borland Turbo Assembler learning 8086/real-mode assembly
  • 搭建x86汇编语言学习环境
  • SpringBoot自动配置
  • 实验p66
  • [Nginx] Nginx学习手册
  • 如何降低信息化系统的构建成本? ——信息化系统省钱全攻略:从规划到运维的实用技巧
  • 2025.10.23总结
  • 诗词大会day1
  • Day2超链接标签