• Vasya and a Tree CodeForces


    题面
    Vasya has a tree consisting of n vertices with root in vertex 1. At first all vertices has 0 written on it.

    Let d(i,j) be the distance between vertices i and j, i.e. number of edges in the shortest path from i to j. Also, let's denote k-subtree of vertex x — set of vertices y such that next two conditions are met:
    题意
    在一棵树上,进行m次操作,每次将结点v的子树上,且与v距离小于等于d的结点加上权值加上x.
    所有操作结束之后,输出每一点的权值.
    思路
    在字树上,同一层结点,与树上根结点的距离都是相等的.
    首先,我们预处理每个结点当了那些操作的根节点.
    dfs遍历到这些节点时,把dep[u]~dep[u]+d的区间加上x
    之后查询ans[u],ans[u]就等于dep[u]的权值
    回溯时再减去x.

    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    
    #define fuck(x) cerr<<#x<<" = "<<x<<endl;
    #define debug(a, x) cerr<<#a<<"["<<x<<"] = "<<a[x]<<endl;
    #define lson l,mid,ls
    #define rson mid+1,r,rs
    #define ls (rt<<1)
    #define rs ((rt<<1)|1)
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int loveisblue = 486;
    const int maxn = 300086;
    const int maxm = 600086;
    const int inf = 0x3f3f3f3f;
    const ll Inf = 999999999999999999;
    const int mod = 1000000007;
    const double eps = 1e-6;
    const double pi = acos(-1);
    
    int dep[maxn];
    
    int Head[maxn],cnt;
    struct edge{
        int Next,v;
    }e[maxm];
    void add_edge(int u,int v){
        e[cnt].Next=Head[u];
        e[cnt].v=v;
        Head[u]=cnt++;
    }
    
    ll ans[maxn];
    
    ll sum[maxn<<2],lazy[maxn<<2];
    
    void push_down(int l,int r,int rt){
        int mid = (l+r)>>1;
        ll len1 = mid-l+1;
        ll len2 = r-mid;
    
        sum[ls]+=len1*lazy[rt];
        sum[rs]+=len2*lazy[rt];
        lazy[ls]+=lazy[rt];
        lazy[rs]+=lazy[rt];
        lazy[rt]=0;
    }
    
    void update(int l,int r,int rt,int L,int R,int val){
        if(L<=l&&R>=r){
            sum[rt]+=1ll*(r-l+1)*val;
            lazy[rt]+=val;
            return;
        }
        if(lazy[rt]){push_down(l,r,rt);}
        int mid = (l+r)>>1;
        if(L<=mid)update(lson,L,R,val);
        if(R>mid){update(rson,L,R,val);}
    }
    
    ll query(int l,int r,int rt,int pos){
    
        if(l==r){
            return sum[rt];
        }
        if(lazy[rt]){push_down(l,r,rt);}
        int mid = (l+r)>>1;
        if(pos<=mid){
            return query(lson,pos);
        }else{
            return query(rson,pos);
        }
    
    }
    int mx=0;
    struct node{
        int d,x;
    };
    
    vector<node>vec[maxn];
    void dfs(int u,int fa,int d){
        dep[u]=d;
        for(int k=Head[u];k!=-1;k=e[k].Next){
            int v=e[k].v;
            if(v==fa){ continue;}
            dfs(e[k].v,u,d+1);
        }
        mx=max(mx,d);
    }
    
    void dfs1(int u,int fa){
        int siz =vec[u].size();
        for(int i=0;i<siz;i++) {
            update(1, mx, 1, dep[u], min(dep[u] + vec[u][i].d,mx),vec[u][i].x);
        }
        ans[u]+=query(1,mx,1,dep[u]);
        for(int k=Head[u];k!=-1;k=e[k].Next){
            int v=e[k].v;
            if(v==fa){ continue;}
            dfs1(e[k].v,u);
        }
    
        for(int i=0;i<siz;i++) {
            update(1, mx, 1, dep[u], min(dep[u] + vec[u][i].d,mx),-vec[u][i].x);
        }
    
    }
    
    
    
    int main() {
        ios::sync_with_stdio(true);
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    
    
        memset(Head,-1,sizeof(Head));
        int n;
        scanf("%d",&n);
        for(int i=1;i<n;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            add_edge(x,y);
            add_edge(y,x);
        }
    
        int m;
        scanf("%d",&m);
        dfs(1,0,1);
        for(int i=1;i<=m;i++){
            int v,d,x;
            scanf("%d%d%d",&v,&d,&x);
            vec[v].push_back({d,x});
        }
    
        dfs1(1,0);
    
    
        for(int i=1;i<=n;i++){
            printf("%lld ",ans[i]);
        }
    
    
        return 0;
    }
    
    
  • 相关阅读:
    excel批量导入后 数据库校验存储过程
    编译内核时覆盖KBUILD_BUILD_USER和KBUILD_BUILD_HOST
    EDID真实数据块,请参考标准文档仔细核对
    RK30SDK开发板驱动分析(二):DDR频率配置
    Linux中的固件加载例子
    Android中如何禁止音量调节至静音
    C++中内部类访问外部类的私有成员
    DSD, DFF, DSF, DST概念解析
    Android中播放DSD音乐
    Linux系统调用分析
  • 原文地址:https://www.cnblogs.com/ZGQblogs/p/11474298.html
Copyright © 2020-2023  润新知