1. 程式人生 > >Codeforces 1076 E - Vasya and a Tree

Codeforces 1076 E - Vasya and a Tree

E - Vasya and a Tree

思路:

dfs動態維護關於深度樹狀陣列

返回時將當前節點的所有操作刪除就能保證每次訪問這個節點時只進行過根節點到當前節點這條路徑上的操作

程式碼:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//
#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pli pair<LL, int> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define
fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 3e5 + 10; vector<int> g[N]; vector<pii> que[N]; LL bit[N], ans[N]; int n; void add(int x, int d) { while(x <= n) bit[x] += d, x += x&-x; } LL sum(
int x) { LL ans = 0; while(x) ans += bit[x], x -= x&-x; return ans; } void dfs(int u, int o, int deep) { for (pii t : que[u]) { int d = t.fi; int x = t.se; int l = deep; int r = min(deep+d, n); add(l, x); add(r+1, -x); } ans[u] = sum(deep); for (int v : g[u]) { if(v != o) dfs(v, u, deep+1); } for (pii t : que[u]) { int d = t.fi; int x = t.se; int l = deep; int r = min(deep+d, n); add(l, -x); add(r+1, +x); } } int main() { int u, m, v, d, x; scanf("%d", &n); for (int i = 1; i < n; i++) { scanf("%d %d", &u, &v); g[u].pb(v); g[v].pb(u); } scanf("%d", &m); for (int i = 1; i <= m; i++) { scanf("%d %d %d", &v, &d, &x); que[v].pb({d, x}); } dfs(1, 1, 1); for (int i = 1; i <= n; i++) printf("%lld%c", ans[i], " \n"[i==n]); return 0; }