zoukankan      html  css  js  c++  java
  • 1076E/Educational Codeforces Round 54-E. Vasya and a Tree<<dfs序 树状数组

    题意

    给定一棵树,初始每个节点权值为零,q次更改,每次修改将以v为顶点的深度为d的子树全部加上x,最后输出所有节点的权重。

    思路

    题目只要求每个点最后的值,那么经过观察,发现一个点最后的权值大小只与他的父节点的更新有关,那么我们就只需要考虑他的父节点到他这条链上的情况,把这条链拿出来成为线段,然后维护后缀和就能得到此点上的权值。每个节点的贡献为给$[h,h+d]$增加$x$,所以维护时,只要在$h+d$点上加上$x$即可。

    但是问题考察的是一棵树,我们就需要动态来完成这条链,我们采用dfs序去扫描这棵树,当一个节点进入时,把他的贡献算上,退出时减去他的贡献,这样就能保证他不会影响别的链。

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef pair<int,int> PII;
     4 const int maxn=3e5+7;
     5 vector<PII> query[maxn];
     6 vector<int> G[maxn];
     7 long long tree[maxn];
     8 long long ans[maxn];
     9 int depth[maxn],reflect[maxn];
    10 int st[maxn],ed[maxn];
    11 void dfs(int now,int far)
    12 {
    13     static int tot=0;
    14     st[now]=++tot;
    15     reflect[tot]=now;
    16     if(far==-1)
    17     {
    18         depth[now]=1;
    19     }
    20     for(int i=0;i<G[now].size();i++)
    21     {
    22         int v=G[now][i];
    23         if(v==far) continue;
    24         depth[v]=depth[now]+1;
    25         dfs(v,now);
    26     }
    27     ed[now]=tot;
    28 }
    29 void add(int x,int v)
    30 {
    31     while(x<maxn)
    32     {
    33         tree[x]+=v;
    34         x+=x&-x;
    35     }
    36 }
    37 long long sum(int x)
    38 {
    39     long long ret=0;
    40     while(x>0)
    41     {
    42         ret+=tree[x];
    43         x-=x&-x;
    44     }
    45     return ret;
    46 }
    47 int main()
    48 {
    49     int n;
    50     memset(tree,0,sizeof(tree));
    51     scanf("%d",&n);
    52     for(int i=1,u,v;i<=n-1;i++)
    53     {
    54         scanf("%d%d",&u,&v);
    55         G[u].push_back(v);
    56         G[v].push_back(u);
    57     }
    58     dfs(1,-1);//跑出dfs序
    59     int q;
    60     scanf("%d",&q);
    61     while(q--)//存储所有询问,将他们按节点分开转换为dfs序的树上顺序
    62     {
    63         int v,d,x;
    64         scanf("%d%d%d",&v,&d,&x);
    65         d+=depth[v];
    66         d=min(d,n);
    67         query[st[v]].push_back(make_pair(d,x));
    68         query[ed[v]+1].push_back(make_pair(d,-x));//在退出时清除贡献
    69     }
    70     for(int i=1;i<=n;i++)
    71     {
    72         for(int j=0;j<query[i].size();j++)//把这个节点上更新的都更新了
    73         {
    74             PII temp=query[i][j];
    75             add(temp.first,temp.second);
    76         }
    77         ans[reflect[i]]=sum(n)-sum(depth[reflect[i]]-1);//映射返回得到答案
    78     }
    79     for(int i=1;i<=n;i++)
    80     {
    81         printf("%lld ",ans[i]);
    82     }
    83 }
  • 相关阅读:
    elasticsearch 插件 大全
    ElasticSearch 服务搭建
    限制玻尔兹曼机(Restricted Boltzmann Machine)RBM
    卷积神经网络
    [转]MATLAB cell数据类型
    [转]matlab语言中的assert断言函数
    [转]matlab中squeeze函数的用法,numel的用法
    Sparse autoencoder implementation 稀疏自编码器实现
    MATLAB中的randi函数
    可视化自编码器训练结果&稀疏自编码器符号一览表
  • 原文地址:https://www.cnblogs.com/computer-luo/p/9970985.html
Copyright © 2011-2022 走看看