https://codeforces.com/contest/1076/problem/E

题意

给一棵树(n<=3e5),m(3e5)次查询,每次查询u,d,x,表示在u的子树中,给距离u<=d,的每个点权值加上x,最后输出每个点的权值

思路

  • 每个点的权值和子节点的修改无关
  • 利用dfs的性质,可以用差分数组顺着每一条路径,在每一个点,维护前缀和(计算出当前点的答案),遍历对当前点的询问维护后面点的权值(用差分标记)
  • 因为到u点距离相等的点,深度一定相等,加上dfs先往深处搜的性质(dfs每搜到一个叶子,实际上对应着一条唯一(深度相等的点只有一个)的路径),所以差分数组只需要用深度做下标即可,返回的时候需要清空当前节点对后面节点的差分修改
#include<bits/stdc++.h>
#define ll long long
#define M 300005
#define pb push_back
using namespace std;
struct N{
int d;ll v;
};
ll sum[M],d[M];
vector<N>p[M];
vector<int>g[M];
int n,i,u,v,m,D;
void dfs(int u,int fa,int dep){
sum[u]=sum[fa]+d[dep];
for(int i=0;i<p[u].size();i++){
N x=p[u][i];
sum[u]+=x.v;
if(dep+x.d+1<n)d[dep+x.d+1]-=x.v;
}
for(int i=0;i<g[u].size();i++){
int v=g[u][i];if(v==fa)continue;
dfs(v,u,dep+1);
}
for(int i=0;i<p[u].size();i++){
N x=p[u][i];
if(dep+x.d+1<n)d[dep+x.d+1]+=x.v;
}
} int main(){
cin>>n;
for(i=0;i<n-1;i++){
scanf("%d%d",&u,&v);
g[u].pb(v);g[v].pb(u);
}
cin>>m;
while(m--){
scanf("%d%d%d",&u,&D,&v);
p[u].pb(N{D,v});
}
dfs(1,0,0);
for(i=1;i<=n;i++)printf("%lld ",sum[i]);
}

最新文章

  1. EF 在controller 带参数跳转到新的网址
  2. .net数据库操作
  3. js中Array自定义contains, indexOf, delete方法.
  4. 13.allegro 颜色设置[原创]
  5. poll机制分析
  6. Eclipse SVN插件冲突导致不能使用解决办法
  7. Validation
  8. Java学习----设计正真的应用程序
  9. s3c2440栈分配情况(fl2440裸机 stack)
  10. 对js原型对象的拓展和原型对象的重指向的区别的研究
  11. SpringCloud学习笔记(3)——Hystrix
  12. linux的一些基础命令
  13. Babel插件:@babel/plugin-transform-runtime
  14. LIBS入门
  15. JAVA学习路线——匹马行天下
  16. Halcon 2D测量
  17. MS SQL Server字符拆分函数
  18. Eclipse打不开 提示an error has occurred.see the log file
  19. 关于redis常用命令
  20. Scrum Meeting 11.06

热门文章

  1. 802.1X技术介绍
  2. c#: 打开文件夹并选中文件
  3. To be a better me
  4. Windows如何安装Android SDK
  5. cell设置背景颜色为啥不起作用
  6. win10下安装配置mysql-8.0.13
  7. EntityFramework的linq扩展where
  8. 如何指定vim 的查找是从上往下还是从下往上[z]
  9. 在windows7中配置ant环境变量
  10. Vue 快速原型开发