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:把 ...
随机推荐
- Spring解决循环依赖
1.Spring解决循环依赖 什么是循环依赖:比如A引用B,B引用C,C引用A,它们最终形成一个依赖环. 循环依赖有两种 1.构造器循环依赖 构造器注入导致的循环依赖,Spring是无法解决的,只能抛 ...
- GIT上传下载报错:[You do not have permission to pull from the repository]的解决方案!
第一步:打开我的电脑 第二步:选择此电脑,右击弹出框点击属性进入控制面板 第三步:进入控制面板 第四步:搜索管理凭据 第五步:编点击右侧按钮,进行编辑用户名和密码的操作添加凭据 git:https:/ ...
- app = Flask(__name__) 是个什么东西
"""第一部分,初始化:所有的Flask都必须创建程序实例, web服务器使用wsgi协议,把客户端所有的请求都转发给这个程序实例 程序实例是Flask的对象,一般情况下 ...
- JS 常用字符串,数组操作
JavaScript String/Array对象 JS String对象 String 对象属性 属性 描述 constructor 对创建该对象的函数的引用 length 字符串的长度 pro ...
- ArcMap基于Oracle出现sde.instances_util.check_instance_table_conflicts:: ORA-00942:表或视图不存在/table or view doesnot exist解决思路
SDE环境:Oracle12C+ArcMap10.7+WinServer2012 出现问题情况: 1.SDE可以连接正常打开,但就是无法新建要素.导入要素等: 1)在根目录新建或导入要素,弹出提示: ...
- 阿里云epel源
epel是个好东西,不过国外的速度实在是不能忍受.所以 有了这篇文章.1. 首先卸载以前装的epel以免影响 rpm -e epel-release 2. 下载阿里提供的epel wget -P /e ...
- Python Tuple元组的操作说明
Tuple的特性在于,它的元素是不可变的(immutable),一旦设定,就不能使用索引去修改. >>> t1=1,2,3,4,5 #给Tuple赋值 >>> t1 ...
- log4j日志记录到数据库
log4j API提供 org.apache.log4j.jdbc.JDBCAppender 对象,它能够将日志信息在指定的数据库. JDBCAppender 配置: Property 描述 buff ...
- Scrapy框架: settings.py设置
# -*- coding: utf-8 -*- # Scrapy settings for maitian project # # For simplicity, this file contains ...
- c数据结构的字符串查找的Brute-Force算法
#include<stdio.h> #include<malloc.h> #include<string.h> //定义字符串的结构体 typedef struct ...