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:把 ...
随机推荐
- centos 安装mysql冲突解决方法
[root@centos-50 servers]# rpm -ivh mysql-server-5.5.33-1.linux2.6.x86_64.rpm Preparing... ########## ...
- POJ 2528(线段树+离散化+特殊离散化)网上博客很少有人真正写对!!! 是POJ数据太水...
Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral electio ...
- Alpha冲刺阶段博客目录
Alpha冲刺阶段博客目录 Scrum Meeting 时间 链接 内容 第六周 https://www.cnblogs.com/error0/p/11815255.html 需求分析 第七周 htt ...
- 送礼物(二分加双向DFS)
题目链接 题意:给你n个礼物重量,给你一个M力量,看你一次性搬动不超过M的礼物重量. 思路:看似背包,但M太大.所以要用DFS,但n也有45,所以考虑双向DFS先搜前半部分满足情况的所有重量,然后去重 ...
- STemWin5.22移植笔记(flyheart)
看了野火ISO开发板移植的emWin,感觉不错,但是没有写移植教程,通过摸索与百度知道了移植的过程!下面和大家分享一下 emWin是segger公司出的一款图形化界面,非常好看,大家所熟悉的ucGUI ...
- 如何在android studio中cordova的混合开发
基于Android Studio 中Cordova的开发 cordova简介 Cordova的前身是PhoneGap 官网: (http://cordova.io) Cordova应是运行在客户端本地 ...
- AutoMapper用法 转载https://www.cnblogs.com/youring2/p/automapper.html
AutoMapper是对象到对象的映射工具.在完成映射规则之后,AutoMapper可以将源对象转换为目标对象. 配置AutoMapper映射规则 AutoMapper是基于约定的,因此在实用映射之前 ...
- DataFrame读取CSV文件
读取csv的代码: print pd.read_csv("ex1.csv") print "\n" print "Can also use read ...
- jmeter压测、操作数据库、分布式、 linux下运行的简单介绍
一.jmeter压测 1.如何压测 常规性能压测:10-15分钟 稳定性测试:一周.2天等 如果想要压测10分钟,勾选永远,勾选调度器,填写600秒.也可以使用固定启动时间. 2.tps.响应时间 ( ...
- os.fork()----linux
fork() 函数,它也属于一个内建并 且只在 Linux 系统下存在. 它非常特殊普通的函数调用,一次返 回但是 fork() 调用一次,返回两次.因为操作系统自动把当前进程(称为父)复制了一份(称 ...