CF1076E(dfs+树上差分)
Posted yyys-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1076E(dfs+树上差分)相关的知识,希望对你有一定的参考价值。
对于一个点,每次把其距离d范围内的都加上x(包括自己)。
所有操作后再输出答案。
考虑dfs的过程,一定是从根向子树里走,往下走的d级一定是需要修改的。
所以我们考虑差分打标记。每次打在d+1的位置
每次用sum维护当前点的答案,到d+1级的时候减去标记即可。
#include<bits/stdc++.h> #define LL long long #define N 300003 #define re register using namespace std; int read() { int x=0,f=1;char s=getchar(); while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();} while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();} return x*f; } struct EDGE{ int nextt,to; }w[N*2]; struct mark{ int d,val; }; int n,m; int tot=0; int head[N],dep[N]; LL b[N],ans[N]; vector<mark>V[N]; void add(int a,int b) { tot++; w[tot].nextt=head[a]; w[tot].to=b; head[a]=tot; } void dfs(int x,int fa,LL sum) { sum+=b[dep[x]]; for(int i=0;i<V[x].size();++i) { sum+=V[x][i].val; if(dep[x]+V[x][i].d+1<=n) b[dep[x]+V[x][i].d+1]-=V[x][i].val; } ans[x]=sum; for(int i=head[x];i;i=w[i].nextt) { int v=w[i].to; if(v==fa)continue; dep[v]=dep[x]+1; dfs(v,x,sum); } for(int i=0;i<V[x].size();++i) { if(dep[x]+V[x][i].d+1<=n) b[dep[x]+V[x][i].d+1]+=V[x][i].val; } } int main() { n=read(); for(int i=1;i<n;++i) { int a=read(),b=read(); add(a,b);add(b,a); } m=read(); for(int i=1;i<=m;++i) { int v=read(),d=read(),x=read(); V[v].push_back(mark{d,x}); } dep[1]=1; dfs(1,1,0); for(int i=1;i<=n;++i)printf("%lld ",ans[i]); } /* */
以上是关于CF1076E(dfs+树上差分)的主要内容,如果未能解决你的问题,请参考以下文章
Cf #292 DDrazil and Morning Exercise(树的直径,树上差分)