Codeforces 1076E Vasya and a Tree(树状数组)
Posted pkgunboat
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 1076E Vasya and a Tree(树状数组)相关的知识,希望对你有一定的参考价值。
题意:给你一颗以1为根节点的树,初始所有节点的权值为0,然后有m个操作,每个操作将点x的所有距离不超过d的节点权值+1,问经过m次操作后每个节点权值是多少?
思路:如果是一个序列,就可以直接用树状数组做,但这是一颗树,所以我们可以想办法把它转化成序列。我们可以先求出每个节点的dfs序,以及深度和子树的大小,顺便记录每个深度都有哪些节点,子树的大小用来确认以该节点为根的子树在dfs序中的范围,此时便可用树状数组维护了。之后,我们把每个操作按能影响到的深度从大到小排序,即优先处理影响深度大的操作。设当前计算的深度为now,假设所有操的作影响的深度大于now的操作已经计算。如果当前操作影响的深度小于now,说明所有能影响到now深度的操作已经全部操作完了,此时把所有深度为now的节点权值计算出来。每读取一个操作的信息,就把操作产生的影响用树状数组维护,因为影响now深度的节点权值已经计算完毕了,所以我把以该操作的操作节点为根的子树全部加上操作的值 对之前已经计算的答案没有影响。操作全部完成后,深度从深到浅计算答案即可。
代码:
#include<bits/stdc++.h> #define LL long long #define lowbit(x) (x&(-(x))) using namespace std; const int maxn=300010; int deep[maxn],head[maxn],Next[maxn*2],ver[maxn*2],tot,cnt; int sum[maxn],sz[maxn],dfsn[maxn],mx,n; LL c[maxn],ans[maxn]; struct op{ int x,d; LL num; bool operator <(const op& rhs)const{ return (deep[x]+d)>(deep[rhs.x]+rhs.d); } }OP[maxn]; void adde(int x,int y){ ver[++tot]=y; Next[tot]=head[x]; head[x]=tot; } vector<int>re[maxn]; int get_deep(int x,int dep){ deep[x]=dep; dfsn[x]=++cnt; sz[x]=1; mx=max(mx,dep); re[dep].push_back(x); for(int i=head[x];i;i=Next[i]){ int y=ver[i]; if(!deep[y]){ get_deep(y,dep+1); sz[x]+=sz[y]; } } } LL ask(int x){ LL ans=0; for(;x;x-=lowbit(x))ans+=c[x]; return ans; } void add(int x,LL y){ for(;x<=n;x+=lowbit(x))c[x]+=y; } int main(){ int m; scanf("%d",&n); for(int i=1;i<n;i++){ int a,b; scanf("%d%d",&a,&b); adde(a,b); adde(b,a); } get_deep(1,1); scanf("%d",&m); for(int i=1;i<=m;i++){ int a,b; LL c; scanf("%d%d%lld",&a,&b,&c); OP[i]=(op){a,b,c}; } sort(OP+1,OP+1+m); int now=mx; for(int i=1;i<=m;i++){ int tmp=deep[OP[i].x]+OP[i].d; while(now>tmp){ for(int j=0;j<re[now].size();j++){ int x=re[now][j]; ans[x]=ask(dfsn[x]); } now--; } add(dfsn[OP[i].x],OP[i].num); add(dfsn[OP[i].x]+sz[OP[i].x],-OP[i].num); } while(now){ while(now){ for(int j=0;j<re[now].size();j++){ int x=re[now][j]; ans[x]=ask(dfsn[x]); } now--; } } for(int i=1;i<=n;i++) printf("%lld ",ans[i]); }
以上是关于Codeforces 1076E Vasya and a Tree(树状数组)的主要内容,如果未能解决你的问题,请参考以下文章
CF1076E:Vasya and a Tree(DFS&差分)
Codeforces 1051E. Vasya and Big Integers
尺取法 C - Vasya and String CodeForces - 676C
Vasya and Basketball CodeForces - 493C
CodeForces - 837E - Vasya's Function | Educational Codeforces Round 26