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

P1600 [NOIP 2016 提高组] 天天爱跑步 题解

一道好题,如果直接根据玩家去找有多少点能够记录到它,比较难处理。我们可以反过来想,转成统计树上每一个点可以记录多少运动员,那么记录一个运动员有两种情况。

我们不妨设以\(1\)为根,遍历到\(x\)时的深度为\(dep_x\)

第一种情况:点\(x\)位于\(s\)\(lca(s,t)\)的路径上,如图所示:
image

那么显然如果从\(s\)走到\(x\)时候恰好是\(w_x\),那么一定满足\(dep_x-dep_s=w_x\),进行转化可以得到\(dep_x-w_x=dep_s\),这也就意味着对于一个点\(x\),其能捕捉到的点\(s\)需要满足\(dep_x-w_x=dep_s\)

第二种情况:点\(x\)位于\(s\)\(lca(s,t)\)的路径上,如图所示:
image

那么我们仿照第一种情况去列出方程,需要满足从\(s\)走到\(x\)的时候恰好是\(w_x\),那么需要满足\(dep_x-dep_{lca}+dep_s-dep_{lca}=w_x\),即把\(s\)走到\(x\)的路径拆为\(s->lca\)\(lca->x\),移项得到\(2*dep_{lca}-dep_s=dep_x-w_x\),也就是说对于一个点\(x\),它能捕获到的点\(s\)需要满足\(2*dep_{lca}-dep_s=dep_x-w_x\)

对于上面的第一种情况而言,对于一个节点为\(s\)的玩家,它能够通过第一种情况影响到\(s-lca\)路径上的所有点;对于第二种情况而言,对于一个节点为\(s\)的玩家,它能够通过第二种情况影响到\(lca-t\)路径上的所有点,这种情况应该不包含\(lca\),因为\(lca\)我们已经在第一种情况被算进去了。

那么我们应该怎么维护这个信息呢?我们可以用树上差分快速的为两种情况的区间分别进行标记。同时我们现在需要对每个点维护一个可以查询区间中单点值的信息,来查询满足两种情况等式的点有多少,可以每个点用两个值域线段树分别维护第一种情况和第二种情况的信息。

具体做法是,
我们以\(1\)为根开始遍历,算出每个点的深度\(dep_x\)。然后对每个玩家而言,第一种情况在\(s\)的线段树的\(dep[s]\)位置\(+1\)\(fa[lca]\)的线段树的\(dep[fa[lca]]\)位置\(-1\),第二种情况在\(t\)的线段树上进行\(2*dep_{lca}-dep_s\)位置\(+1\),在\(t\)的右节点的线段树上进行\(2*dep_{lca}-dep_s\)位置\(-1\)
最后再次以\(1\)为根进行遍历,合并自己的左右节点的线段树,因为上面的差分操作,我们可以保证第一种情况和第二种情况一定被限制在了\(s->lca->t\)的这条路径上,而不会因为这个标记影响到其他不在路径上的点。

#include <bits/stdc++.h>
using namespace std;const int T=1e7+2,N=3e5+2,P=20;vector<int> e[N];
int n,m;
int sum[T],dep[N],fa[N],ls[T],rs[T];
int w[N],cnt=0;
int rootup[N],rootdown[N];
int st[N][P],ans[N];void up(int i){sum[i]=sum[ls[i]]+sum[rs[i]];
}void dfs1(int u,int last){fa[u]=last;dep[u]=dep[last]+1;st[u][0]=last;for(int p=1;p<P;p++){st[u][p]=st[st[u][p-1]][p-1];}for(int v:e[u]){if(v^last){dfs1(v,u);}}
}int LCA(int a,int b){if(dep[a]<dep[b]) swap(a,b);for(int i=P-1;i>=0;i--){if(dep[st[a][i]]>=dep[b]) a=st[a][i];}if(a==b) return a;for(int i=P-1;i>=0;i--){if(st[a][i]!=st[b][i]){a=st[a][i],b=st[b][i];}}return st[a][0];
}int add(int ji,int jv,int l,int r,int i){int idx=i;if(!idx) idx=++cnt;if(l==r){sum[idx]+=jv;return idx;}int mid=(l+r)>>1;if(ji<=mid) ls[idx]=add(ji,jv,l,mid,ls[idx]);else rs[idx]=add(ji,jv,mid+1,r,rs[idx]);up(idx);return idx;
}int merge(int l,int r,int t1,int t2){if(t1==0||t2==0) return t1+t2;if(l==r){sum[t1]+=sum[t2];}else{int mid=(l+r)>>1;ls[t1]=merge(l,mid,ls[t1],ls[t2]);rs[t1]=merge(mid+1,r,rs[t1],rs[t2]);up(t1);}return t1;
}int query(int ji,int l,int r,int i){if(ji<l||ji>r||i==0) return 0;if(l==r){return sum[i];}int mid=(l+r)>>1;if(ji<=mid) return query(ji,l,mid,ls[i]);else return query(ji,mid+1,r,rs[i]);
}void dfs2(int u,int last){for(int v:e[u]){if(v^last){dfs2(v,u);rootup[u]=merge(1,n,rootup[u],rootup[v]);rootdown[u]=merge(-n,n,rootdown[u],rootdown[v]);}}ans[u]=ans[u]+query(dep[u]+w[u],1,n,rootup[u])+query(dep[u]-w[u],-n,n,rootdown[u]);
}int main(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);cin>>n>>m;for(int i=1;i<=n-1;i++){int u,v;cin>>u>>v;e[u].push_back(v),e[v].push_back(u);}for(int i=1;i<=n;i++) cin>>w[i];dfs1(1,0);for(int i=1;i<=m;i++){int s,t;cin>>s>>t;int lca=LCA(s,t);rootup[s]=add(dep[s],1,1,n,rootup[s]);rootup[fa[lca]]=add(dep[s],-1,1,n,rootup[fa[lca]]);rootdown[t]=add(2*dep[lca]-dep[s],1,-n,n,rootdown[t]);rootdown[lca]=add(2*dep[lca]-dep[s],-1,-n,n,rootdown[lca]);}dfs2(1,0);for(int i=1;i<=n;i++) cout<<ans[i]<<" ";return 0;
}

总结:直接计算答案比较困难的时候,可以用拆贡献的思想,从另外一个角度出发统计每种情况的贡献。
维护树上区间信息可以采用树上差分,需要维护每个点的区间信息并需要对子树节点的信息进行合并的时候可以采用线段树合并的方法。

http://www.jsqmd.com/news/440764/

相关文章:

  • 2026年评价高的光照振荡培养箱品牌推荐:立式恒温振荡培养箱/台式恒温振荡培养箱/大容量恒温振荡培养箱实力品牌厂家推荐 - 行业平台推荐
  • 2026年靠谱的工业高速摄像机工厂推荐:高速摄像机应用场景制造厂家哪家靠谱 - 行业平台推荐
  • 2026年评价高的电动振动台工厂推荐:小型振动台/高频振动台/三综合振动台优质供应商推荐 - 行业平台推荐
  • 2026年3月西安静电地板厂家推荐榜:厂房、净化车间、学校、医院、办公楼静电地板选择指南,陕西众鑫本地专业机房设备精选 - 海棠依旧大
  • 2026年质量好的超高速相机工厂推荐:科研高速相机/工业高速相机/高速相机应用场景厂家选择指南 - 行业平台推荐
  • 代码随想录算法训练营第二天| 209.长度最小的子数组、59.螺旋矩阵II、区间和
  • 2026年比较好的事件相机系统公司推荐:DVS传感器事件相机生产商哪家强 - 行业平台推荐
  • 2026年专业深度测评:抖店代运营厂家排名前五权威榜单 - 电商资讯
  • 2026年口碑好的冷冻浓缩干燥器品牌推荐:离心浓缩干燥器/冷冻离心浓缩干燥器/真空离心浓缩干燥器生产厂家推荐几家 - 行业平台推荐
  • 3-5午夜盘思
  • 蓝桥/15/B/4 数字接龙
  • yolov11训练流程 - MKT
  • 数据交易可视化分析:PowerBI实战案例教程
  • 直击痛点!AI应用架构师对金融市场AI监控系统的改进思路
  • 2026年优秀的辊筒输送机厂家推荐:滚筒输送机/链条输送机专业制造厂家推荐 - 行业平台推荐
  • 2026年诚信的共板法兰风管工厂推荐:漂珠硅晶防火风管厂家综合实力对比 - 行业平台推荐
  • 5.42.三种类型的补偿网络(1-传递、策略)
  • 亲测不踩雷!5 家高口碑小程序制作公司,无隐形消费 - 企业数字化改造和转型
  • 2026年热门的载带成型机工厂推荐:载带成型机实力品牌厂家推荐 - 行业平台推荐
  • SolidWorks二次开发(C#)-swDoc.IGetActiveConfiguration获取当前配置属性-删除所有属性
  • python: Flyweight Pattern
  • 2026 杭州小程序开发公司排名 TOP10|权威盘点与选型指南 - 企业数字化改造和转型
  • 2026 小程序服务商深度盘点:定制 / 模板 / 商城全覆盖 - 企业数字化改造和转型
  • 2026年知名的铁罐工厂推荐:马口铁罐/铁罐定制/蛋卷铁罐品牌厂家哪家靠谱 - 行业平台推荐
  • 2026年知名的烽创挂面机工厂推荐:烽创面条生产线生产商哪家强 - 行业平台推荐
  • 图像分类任务-猫狗大战(计算机视觉领域区分猫和狗照片)
  • 【Python高级编程】近似串匹配 - 详解
  • 霍尔流量计设计和脉冲计数
  • 2026年热门的南京热机械疲劳试验机品牌推荐:南京旋转弯曲疲劳试验机厂家推荐与选购指南 - 行业平台推荐
  • 2026年质量好的亚克力加工厂家推荐:亚克力制品实力工厂推荐 - 行业平台推荐