CodeForces - 1076E

Problem Description:

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:

   x is the ancestor of y (each vertex is the ancestor of itself);
   d(x,y)≤k.
Vasya needs you to process m queries. The i-th query is a triple vi, di and xi. For each query Vasya adds value xi to each vertex from di-subtree of vi. Report to Vasya all values, written on vertices of the tree after processing all queries.

Input:

The first line contains single integer n (1≤n≤3⋅105) — number of vertices in the tree.

Each of next n−1 lines contains two integers x and y (1≤x,y≤n) — edge between vertices x and y. It is guarantied that given graph is a tree.

Next line contains single integer m (1≤m≤3⋅105) — number of queries.

Each of next m lines contains three integers vi, di, xi (1≤vi≤n, 0≤di≤109, 1≤xi≤109) — description of the i-th query.

Output:

Print n integers. The i-th integers is the value, written in the i-th vertex after processing all queries.

  这道题是个树上查分应该是比较好看出来的(尽管我看了很久),差分我就不YY了,主要是用什么来维护区间修改。

  方法也是比较多的,有大佬再加了一个差分(详见 gushui博客),也有大佬用树状数组(详见 zqs博客),更有大佬用线段树(这位大佬没有写博客,所以没有链接)。但是,差分和树状数组都要跑两边DFS,还要二分一下,线段树码量大,而且以上方法都带log,是O(n log n)的。

  下面我来YY一哈O(n)的线性做法:

  首先读入图 和 询问,然后我们开始DFS,需要记一个类似于Lasy标记的东西(Code中的V[]),可以求出Ans(详见代码)。

  ("O2+O3+fread" 跑得飞快,200ms)

  Code:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
int n,m,Deep[300005],Cnt,Head[300005],Next[600005],To[600005];
long long V[300005],Ans[300005];
struct node {int Deep,V;}A[300005];
vector<node>Q[300005];
#define gc (p1==p2&&(p2=(p1=buf)+fread(buf,1,65536,stdin),p1==p2)?EOF:*p1++)
char buf[65536],*p1,*p2;
inline int read()
{
char ch;int x(0);
while((ch=gc)<48);
do x=x*10+ch-48;while((ch=gc)>=48);
return x;
}
inline void ADD(int x,int y) {Next[++Cnt]=Head[x],Head[x]=Cnt,To[Cnt]=y,Next[++Cnt]=Head[y],Head[y]=Cnt,To[Cnt]=x;}
inline void DFS(int x,int fa,long long Sum)
{
Sum+=V[Deep[x]];
for(register int i=0;i<(int)Q[x].size();++i)
{
Sum+=Q[x][i].V;
if(Deep[x]+Q[x][i].Deep+1<=n) V[Deep[x]+Q[x][i].Deep+1]-=Q[x][i].V;
}
Ans[x]=Sum;
for(register int i=Head[x],j;i;i=Next[i])
{
j=To[i];
if(j==fa) continue;
Deep[j]=Deep[x]+1,DFS(j,x,Sum);
}
for(register int i=0;i<(int)Q[x].size();++i)
if(Deep[x]+Q[x][i].Deep+1<=n) V[Deep[x]+Q[x][i].Deep+1]+=Q[x][i].V;
}
int main()
{
n=read();
for(register int i=1,x,y;i<n;++i) x=read(),y=read(),ADD(x,y);
m=read();
for(register int i=1,x,y,z;i<=m;++i) x=read(),y=read(),z=read(),Q[x].push_back(node{y,z});
Deep[1]=1,DFS(1,0,0);
for(register int i=1;i<=n;++i) printf("%lld ",Ans[i]);
return 0;
}

CodeForces-1076E Vasya and a Tree的更多相关文章

  1. Codeforces 1076E Vasya and a Tree(树状数组)或dfs

    题意:给你一颗以1为根节点的树,初始所有节点的权值为0,然后有m个操作,每个操作将点x的所有距离不超过d的节点权值+1,问经过m次操作后每个节点权值是多少? 思路:如果是一个序列,就可以直接用树状数组 ...

  2. codeforces 1076E Vasya and a Tree 【dfs+树状数组】

    题目:戳这里 题意:给定有n个点的一棵树,顶点1为根.m次操作,每次都把以v为根,深度dep以内的子树中所有的顶点(包括v本身)加x.求出最后每个点的值为多少. 解题思路:考虑到每次都只对点及其子树操 ...

  3. 1076E - Vasya and a Tree(图的遍历)

    题意:给出一棵根节点为1的树,执行m次修改操作,每次修改为a,b,c,表示a节点的子树中,距离a小于等于b的子节点的权值加上c,求m次操作后每个节点的权值 分析:用线段树维护每层节点的权值,然后dfs ...

  4. CF 1076E Vasya and a Tree(线段树+树剖)

    传送门 解题思路 首先按照每个修改时\(x\)的深度\(+d\)从大到小排序,然后按照深度分层,一层一层的修改,修改的时候就直接暴力修改子树,然后每做完一层把答案都取下来,因为以后的所有修改的深度都小 ...

  5. Vasya and a Tree CodeForces - 1076E(线段树+dfs)

    I - Vasya and a Tree CodeForces - 1076E 其实参考完别人的思路,写完程序交上去,还是没理解啥意思..昨晚再仔细想了想.终于弄明白了(有可能不对 题意是有一棵树n个 ...

  6. Vasya and a Tree CodeForces - 1076E (线段树 + dfs)

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

  7. Codeforces 1076 E - Vasya and a Tree

    E - Vasya and a Tree 思路: dfs动态维护关于深度树状数组 返回时将当前节点的所有操作删除就能保证每次访问这个节点时只进行过根节点到当前节点这条路径上的操作 代码: #pragm ...

  8. Codeforces1076E. Vasya and a Tree(dfs+离线+动态维护前缀和)

    题目链接:传送门 题目: E. Vasya and a Tree time limit per test seconds memory limit per test megabytes input s ...

  9. codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(启发式合并)

    codeforces 741D Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths 题意 给出一棵树,每条边上有一个字符,字符集大小只 ...

随机推荐

  1. 随机生成uuid序号

    function guid() { function S4() { return (((1+Math.random())*0x10000)|0).toString(16).substring(1); ...

  2. 利用k8s yaml配置文件起一个http能够让外部访问

    1.首先建一个http的Deployment apiVersion: apps/v1 #版本信息 kind: Deployment #文件类型 metadata: #Deployment资源的元数据信 ...

  3. CPU到底是什么东西?它为什么能够执行数学运算?

    CPU到底是什么东西?它为什么能够执行数学运算? 本文地址http://yangjianyong.cn/?p=20转载无需经过作者本人授权 简单的物理电路 先来看一张初中学过的物理电路图: 从图中我们 ...

  4. swiper-wrapper轮滑组件(多组轮滑界面)间隔无效问题

    在多组此种轮滑效果出现时,你需要加两个属性值,即 new Swiper('.swiper-container', { slidesPerView: 3, slidesPerColumn: 2, spa ...

  5. Jmeter系列(27)- 常用逻辑控制器(6) | 如果(if)控制器If Controller

    如果(if)控制器(If Controller) 在实际工作中,当使用JMeter做性能脚本或者接口脚本时,当遇到需要对不同的条件做不同的操作时,我们可以使用JMeter中if控制器来实现 if控制器 ...

  6. JavaScript进阶面向对象ES6

    类和对象 对象:万物皆对象,对象是一个具体的事物,看得见摸得着的实物 对象是由属性和方法组成的: 属性:事物的特征,再对象中用属性来表示(常用名词) 方法:事物的行为,再对象中用方法来表示(常用动词) ...

  7. chrome 的手机调试工具 toggle device toolbar

    chrome 的手机调试工具 toggle device toolbar 是否可以模拟到不同系统,如苹果系统和安卓系统.

  8. 鸿蒙内核源码分析(内存分配篇) | 内存有哪些分配方式  | 百篇博客分析OpenHarmony源码 | v11.02

    百篇博客系列篇.本篇为: v11.xx 鸿蒙内核源码分析(内存分配篇) | 内存有哪些分配方式 | 51.c.h .o 内存管理相关篇为: v11.xx 鸿蒙内核源码分析(内存分配篇) | 内存有哪些 ...

  9. CF461D-Appleman and Complicated Task【并查集】

    正题 题目链接:https://www.luogu.com.cn/problem/CF461D 题目大意 \(n*n\)的网格需要填上\(x\)或\(o\),其中有\(k\)个格子已经固定,求有多少中 ...

  10. 踩坑系列《九》 无法获取实体类xxx对应的表名

    话不多说,直接说明原因 类似于 @MapperScan(basePackages = "com.hyxiao.user.mapper") 启动类的mapper扫描注解的导入包正确的 ...