码迷,mamicode.com
首页 > 其他好文 > 详细

CF1076E(dfs+树上差分)

时间:2019-11-07 09:43:37      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:++i   read   dep   printf   维护   技术   space   ace   tchar   

传送门

对于一个点,每次把其距离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]);
} 
/*
*/
View Code

CF1076E(dfs+树上差分)

标签:++i   read   dep   printf   维护   技术   space   ace   tchar   

原文地址:https://www.cnblogs.com/yyys-/p/11809804.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!