传送门

解题思路

  首先按照每个修改时\(x\)的深度\(+d\)从大到小排序,然后按照深度分层,一层一层的修改,修改的时候就直接暴力修改子树,然后每做完一层把答案都取下来,因为以后的所有修改的深度都小于当前层,也就是无法对当前层的节点造成贡献。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector> using namespace std;
const int MAXN = 300005;
typedef long long LL; inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return f?x:-x;
} void out(LL x){
if(!x) return;
out(x/10);putchar('0'+x%10);
} inline void OUT(LL x){
if(!x) putchar('0');
else out(x);
putchar(' ');
} int n,m,head[MAXN],cnt,to[MAXN<<1],nxt[MAXN<<1],Max;
int dep[MAXN],fa[MAXN],son[MAXN],siz[MAXN],id[MAXN],top[MAXN],num;
LL sum[MAXN<<2],tag[MAXN<<2],ans[MAXN];
vector<int> a[MAXN]; struct Query{
int v,d,rt;
friend bool operator<(const Query A,const Query B){
return A.d>B.d;
}
}q[MAXN]; inline int max(int x,int y){
return x>y?x:y;
} inline int min(int x,int y){
return x<y?x:y;
} inline void add(int bg,int ed){
to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
} void dfs1(int x,int f,int d){
dep[x]=d;fa[x]=f;siz[x]=1;Max=max(Max,d);a[d].push_back(x);
int maxson=-1,u;
for(int i=head[x];i;i=nxt[i]){
u=to[i];if(u==f) continue;
dfs1(u,x,d+1);siz[x]+=siz[u];
if(siz[u]>maxson) maxson=siz[u],son[x]=u;
}
} void dfs2(int x,int topf){
top[x]=topf;id[x]=++num;int u;
if(!son[x]) return;dfs2(son[x],topf);
for(int i=head[x];i;i=nxt[i]){
u=to[i];if(u==fa[x] || u==son[x]) continue;
dfs2(u,u);
}
} inline void pushdown(int x,int ln,int rn){
tag[x<<1]+=tag[x];tag[x<<1|1]+=tag[x];
sum[x<<1]+=tag[x]*ln;sum[x<<1|1]+=tag[x]*rn;
tag[x]=0;
} void update(int x,int l,int r,int L,int R,int k){
if(L<=l && r<=R){
sum[x]+=(LL)(r-l+1)*k;
tag[x]+=k;return ;
}
int mid=(l+r)>>1;if(tag[x]) pushdown(x,mid-l+1,r-mid);
if(mid>=L) update(x<<1,l,mid,L,R,k);
if(mid<R) update(x<<1|1,mid+1,r,L,R,k);
sum[x]=sum[x<<1]+sum[x<<1|1];
} LL query(int x,int l,int r,int L){
if(l==r) return sum[x];
int mid=(l+r)>>1;LL ret=0;if(tag[x]) pushdown(x,mid-l+1,r-mid);
if(L<=mid) return query(x<<1,l,mid,L);
else return query(x<<1|1,mid+1,r,L);
} int main(){
n=rd();int x,y,z;
for(int i=1;i<n;i++){
x=rd(),y=rd();
add(x,y),add(y,x);
}
dfs1(1,0,1);dfs2(1,1);m=rd();
for(int i=1;i<=m;i++){
x=rd(),y=rd(),z=rd();
q[i].rt=x;q[i].d=min(dep[x]+y,Max);q[i].v=z;
}
sort(q+1,q+1+m);
for(int i=1;i<=m;i++){
x=q[i].rt,y=q[i].d,z=q[i].v;
if(y!=q[i-1].d)
for(int j=q[i-1].d;j>y;j--)
for(int k=0;k<a[j].size();k++)
ans[a[j][k]]=query(1,1,n,id[a[j][k]]);
update(1,1,n,id[x],id[x]+siz[x]-1,z);
}
for(int i=q[m].d;i;i--)
for(int j=0;j<a[i].size();j++)
ans[a[i][j]]=query(1,1,n,id[a[i][j]]);
for(int i=1;i<=n;i++) OUT(ans[i]);
return 0;
}

CF 1076E Vasya and a Tree(线段树+树剖)的更多相关文章

  1. CF E. Vasya and a Tree】 dfs+树状数组(给你一棵n个节点的树,每个点有一个权值,初始全为0,m次操作,每次三个数(v, d, x)表示只考虑以v为根的子树,将所有与v点距离小于等于d的点权值全部加上x,求所有操作完毕后,所有节点的值)

    题意: 给你一棵n个节点的树,每个点有一个权值,初始全为0,m次操作,每次三个数(v, d, x)表示只考虑以v为根的子树,将所有与v点距离小于等于d的点权值全部加上x,求所有操作完毕后,所有节点的值 ...

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

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

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

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

  4. cf1076E Vasya and a Tree (线段树)

    我的做法: 给询问按$deep[v]+d$排序,每次做到某一深度的时候,先给这个深度所有点的值清0,然后直接改v的子树 官方做法比较妙妙: dfs,进入v的时候给$[deep[v],deep[v]+d ...

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

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

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

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

  7. 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 ...

  8. CF Edu54 E. Vasya and a Tree DFS+树状数组

    Vasya and a Tree 题意: 给定一棵树,对树有3e5的操作,每次操作为,把树上某个节点的不超过d的子节点都加上值x; 思路: 多开一个vector记录每个点上的操作.dfs这颗树,同时以 ...

  9. Water Tree CodeForces 343D 树链剖分+线段树

    Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...

随机推荐

  1. SCP-Py-002

    项目编号:Py-002 项目等级:EuclidKeter 特殊收容措施: Py-002-1目前被映射在Researcher Kevin的服务器位于Site-Pyproject地下防无线电渗透室且被切断 ...

  2. Delphi直接读取XmL

    有时,只需要用XML作一些小的应用,比如只是简单地保存日志或者一些配置,这时我们只需要直接读写XML就好,效率第一. Delphi盒子有一个直接读写XML文件 (例子和代码),其核心函数为下面两个函数 ...

  3. subsequence 2

    题目链接 题意:每次给出两个字母 和 只有这两个字母的原字符串的子序列,最后让你输出原字符串. 思路:先将字符转换为hash值,然后再转换成图,就是一个拓扑排序了,然后满足不了的情况有两种,一个是构造 ...

  4. mysql 用户权限管理详细

    用户管理 mysql>use mysql; 查看 mysql> select host,user,password from user ; 创建 mysql> create user ...

  5. ios 最全的常用字符串操作

    1.将NSData / NSString转化 1 2 3 NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; // 将字符串 ...

  6. 3、jQuery面向对象

    1.首先介绍callback.js对ajax进行了封装 function ajaxFunction(){ var xmlHttp; try{ // Firefox, Opera 8.0+, Safar ...

  7. 11.Jmeter 快速入门教程 -- jmeter事务控制器

    你肯定知道, jmeter是一个跨系统平台的性能测试工具, 比如他可以在linux,freebsd,windows,solaris 等等各种系统上可以运行. 我可以说, 事务 transaction ...

  8. CF_127E reader Display

    这道题其实找到规律之后其实不难,和破损的键盘一样,都有点递推转移的感觉 题意: 你可以进行这样一次操作:选一个点,然后把这个点横切竖切直到正对角线上面的点,全部翻转过来,问你要进行多少次操作才能把所有 ...

  9. 比较全面的CSS hack方式一览

    转载请注明来自CSDN freshlover的博客专栏<史上最全CSS Hack方式一览>   做前端多年,虽然不是经常需要hack,但是我们经常会遇到各浏览器表现不一致的情况.基于此,某 ...

  10. this与super的语法比较

    this 代表当前对象 可以代表当前属性,当前方法,当前对象(整个自己). 作用:解决同名变量的同名问题,同明变量可能来源于父类,局部变量和成员变量... 语法使用:this( 实参... ); 调用 ...