Educational Codeforces Round 54 (Rated for Div. 2)(E. Vasya and a Tree)

链接:http://codeforces.com/contest/1076/problem/E
思路:学到了一种新姿势啊,首先来一次dfs或者bfs给树标上深度,然后来dfs,每次到一个结点查询上面是否有需要更新的,然后用深度代表树状数组的下标,在dep[u]上加上权值,在dep[u]+d+1上减去一个权值,这样对于范围外的点用树状数组求和时就可以刚好抵消使得答案不变,而里面的点就可以得到更新后的答案,然后当遍历完回溯时把加上和扣除的权值还原即可。
代码:

#include
using namespace std;

typedef long long ll;
typedef pair P;
const int maxn = 3e5+100;
ll c[maxn];
ll res[maxn];
int dep[maxn];
vector G[maxn];
int n,m;

vector

ans[maxn]; int lowbit(int x){ return x&(-x); } void add(int x,ll d){ while(xn)d = n; //差分,用dfs当一个偏序,然后在此偏序上用树状数组维护前缀和 add(dep[u],w); add(dep[u]+d+1,-w); } res[u] = query(dep[u]); for(int i=0;in)d = n; //还原 add(dep[u],-w); add(dep[u]+d+1,w); } } int main(){ scanf("%d",&n); for(int i=0;i

你可能感兴趣的:(Educational Codeforces Round 54 (Rated for Div. 2)(E. Vasya and a Tree))