CF 1076E Vasya and a Tree(线段树+树剖)
解题思路
首先按照每个修改时\(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(线段树+树剖)的更多相关文章
- 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,求所有操作完毕后,所有节点的值 ...
- codeforces 1076E Vasya and a Tree 【dfs+树状数组】
题目:戳这里 题意:给定有n个点的一棵树,顶点1为根.m次操作,每次都把以v为根,深度dep以内的子树中所有的顶点(包括v本身)加x.求出最后每个点的值为多少. 解题思路:考虑到每次都只对点及其子树操 ...
- Codeforces 1076E Vasya and a Tree(树状数组)或dfs
题意:给你一颗以1为根节点的树,初始所有节点的权值为0,然后有m个操作,每个操作将点x的所有距离不超过d的节点权值+1,问经过m次操作后每个节点权值是多少? 思路:如果是一个序列,就可以直接用树状数组 ...
- cf1076E Vasya and a Tree (线段树)
我的做法: 给询问按$deep[v]+d$排序,每次做到某一深度的时候,先给这个深度所有点的值清0,然后直接改v的子树 官方做法比较妙妙: dfs,进入v的时候给$[deep[v],deep[v]+d ...
- 1076E - Vasya and a Tree(图的遍历)
题意:给出一棵根节点为1的树,执行m次修改操作,每次修改为a,b,c,表示a节点的子树中,距离a小于等于b的子节点的权值加上c,求m次操作后每个节点的权值 分析:用线段树维护每层节点的权值,然后dfs ...
- Vasya and a Tree CodeForces - 1076E(线段树+dfs)
I - Vasya and a Tree CodeForces - 1076E 其实参考完别人的思路,写完程序交上去,还是没理解啥意思..昨晚再仔细想了想.终于弄明白了(有可能不对 题意是有一棵树n个 ...
- 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 ...
- CF Edu54 E. Vasya and a Tree DFS+树状数组
Vasya and a Tree 题意: 给定一棵树,对树有3e5的操作,每次操作为,把树上某个节点的不超过d的子节点都加上值x; 思路: 多开一个vector记录每个点上的操作.dfs这颗树,同时以 ...
- Water Tree CodeForces 343D 树链剖分+线段树
Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...
随机推荐
- POJ 1655 Balancing Act (树状dp入门)
Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any nod ...
- 【Flutter学习】组件学习之目录
01. Flutter组件-Layout-Container-容器 02. Flutter组件-Text-Text-文本 03. Flutter组件-Text-RichText-富文本 04. ...
- CDN技术详解(七)
动态内容加速服务的实现 随着Web2.0的兴起,产生了动态网页.个性化内容.电子交易数据等内容的加速,这些就涉及了动态内容加速技术. 静态内容的加速,都是对于表现层的加速,对于动态页面等内容的加速,则 ...
- 75、python学习第一篇
1.sys包下边的argv方法,从控制台获取数据 ''' Created on 2017年4月8日 @author: weizhen ''' import sys One = [" * &q ...
- Autofac框架详解 转载https://www.cnblogs.com/lenmom/p/9081658.html
一.组件 创建出来的对象需要从组件中来获取,组件的创建有如下4种(延续第一篇的Demo,仅仅变动所贴出的代码)方式: 1.类型创建RegisterType AutoFac能够通过反射检查一个类型,选择 ...
- Linux中TLS
TLS(Thread Local Storage) 线程局部存储. 在Linux操作系统中,TLS保存成GDT中描述的一个段. 1: /* 2: * This creates a new proces ...
- A + B Problem II HDU - 1002
非常简单的大数加法,因为不会Java只能手写大数加法了;博客存一下以后回来看看 #include<bits/stdc++.h> using namespace std; +; char A ...
- CodeForces - 841B-Godsend-思维
Leha somehow found an array consisting of n integers. Looking at it, he came up with a task. Two pla ...
- mysql与navicat应用
下载安装配置 用法 1.连接本机数据库: 打开navicat选择连接---第一个mysql---在常规下自己明明连接名和密码----确定 我这边建立了本机测试库 2. 连接阿里云服务器上的mysql ...
- ES6 基础内容介绍
参考博客: https://www.cnblogs.com/libin-1/p/6716470.html 一.新的变量声明方式 let/const 与var不同,新的变量声明方式带来了一些不一样的特性 ...