1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| #include <cstdio> #include <cmath> #include <vector>
std::vector<int> sons[300005]; int w[300005], fa[300005][19], Dep[300005], ans[300005], n; void dfs(const int u) { int MAX(ceil(log2(Dep[u] = Dep[fa[u][0]] + 1))); for (int i(1); i <= MAX; ++ i) fa[u][i] = fa[fa[u][i - 1]][i - 1]; for (int v : sons[u]) if (v != fa[u][0]) fa[v][0] = u, dfs(v); } int LCA(int u, int v) { if (Dep[u] < Dep[v]) u ^= v ^= u ^= v; int MAX(ceil(log2(Dep[u] - Dep[v]))); for (int i(0); i <= MAX; ++ i) if (Dep[u] - Dep[v] & 1 << i) u = fa[u][i]; if (u == v) return u; for (int i(ceil(log2(Dep[u]))); i >= 0; -- i) if (fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i]; return fa[u][0]; }
int sum[10000005], ls[10000005], rs[10000005], root[300005], root2[300005], tot; void update(int& O, const int l, const int r, const int p, const int d) { if (!O) O = ++ tot; sum[O] += d; if (l == r) return; const int mid(l + r >> 1); if (p <= mid) update(ls[O], l, mid, p, d); else update(rs[O], mid + 1, r, p, d); } void merge(int &x, const int y, const int l, const int r) { if (!x || !y) {x |= y; return;} sum[x] += sum[y]; if (l == r) return; const int mid(l + r >> 1); merge(ls[x], ls[y], l, mid); merge(rs[x], rs[y], mid + 1, r); } int query(const int O, const int l, const int r, const int p) { if (!O || p < l || r < p) return 0; if (l == r) return sum[O]; const int mid(l + r >> 1); if (p <= mid) return query(ls[O], l, mid, p); else return query(rs[O], mid + 1, r, p); }
void dfs2(const int u) { for (int v : sons[u]) if (v != fa[u][0]) { dfs2(v); merge(root[u], root[v], -n, n); merge(root2[u], root2[v], -n, n); } ans[u] = query(root2[u], 1, n << 1, n + w[u] - Dep[u]) + query(root[u], 1, n << 1, n + Dep[u] + w[u]); }
int main() { int m; scanf("%d%d", &n, &m); for (int i(1); i < n; ++ i) { int u, v; scanf("%d%d", &u, &v); sons[u].push_back(v), sons[v].push_back(u); } dfs(1); for (int i(1); i <= n; ++ i) scanf("%d", w + i); for (int i(1); i <= m; ++ i) { int s, t, lca; scanf("%d%d", &s, &t); lca = LCA(s, t); update(root[s], 1, n << 1, n + Dep[s], 1); update(root2[t], 1, n << 1, n + Dep[s] - Dep[lca] * 2, 1); update(root[lca], 1, n << 1, n + Dep[s], -1); update(root2[fa[lca][0]], 1, n << 1, n + Dep[s] - Dep[lca] * 2, -1); } dfs2(1); for (int i(1); i <= n; ++ i) printf("%d ", ans[i]); return 0; }
|