Problem:
Problem M: Star Gazer
Problem
suta君は夜空を見ていた際に、オリジナルの新しい星座を思いつきました。
思いついた星座は $N$ 個の星からなり、 $N-1$ 本の線で結ばれています。
具体的には、 $i(1 \leq i \leq N-1)$ 本目の線が、 $a_i$ 番目の星と $b_i$ 番目の星を結びます。どの星も、少なくとも1つの別の星と結ばれます。
suta君は、この星座における、 $p(1 \leq p \leq N)$ 番目の星の美しさを次のように定義しました。
$q(1 \leq q \leq N)$ 番目の星の明るさを $l_q$ 、 $p$ 番目の星と $q$ 番目の星の距離を $d_{p,q}$ とし、
		$\displaystyle \sum_{q = 1}^{N} l_q \times d_{p,q}$
ここで $p$ 番目の星と $q$ 番目の星の距離とは、「 $p$ 番目の星から $q$ 番目の星に線を辿っていく時、辿る必要のある線の本数」
	です。
また、 $d_{p,p} = 0$ です。
suta君は星座の完成度を確認するために、それぞれの星の美しさが知りたくなりました。
計算が苦手なsuta君に代わって、星の美しさを計算するプログラムを組んでください！
Constraints
入力は以下の条件を満たす。
$2 \leq N \leq 10^5$
$1 \leq l_i \leq 10^8$
$1 \leq a_i, b_i \leq N$
$a_i \neq b_i$
$(a_i, b_i) = (b_j, a_j)$ もしくは $(a_i, b_i) = (a_j, b_j)$ となるような $i,j(1 \leq i,j \leq N, i \neq j)$ の組み合わせは存在しない。
任意の星からいくつかの線を辿って別の星にたどり着くことができる。
入力は全て整数で与えられる。
Input
入力は以下の形式で与えられる。
$N$
$l_1$ $l_2$ $\ldots$ $l_N$
$a_1$ $b_1$
$a_2$ $b_2$
$\vdots$
$a_{N-1}$ $b_{N-1}$
Output
$N$ 行出力せよ。 $i$ 行目には、 $i$ 番目の星の美しさを出力せよ。
末尾の改行を忘れないこと。
Sample Input 1
4
1 2 3 4
1 2
1 3
3 4
Sample Output 1
13
19
9
11
与えられる星座は図のようになります。
1番目の星の美しさは、
	$1 × 0 + 2 × 1 + 3 × 1 + 4 × 2 = 13$
	となります。
同様に、2番目の星の美しさは、
	$1 × 1 + 2 × 0 + 3 × 2 + 4 × 3 = 19$
	となります。
3番目の星の美しさは、
	$1 × 1 + 2 × 2 + 3 × 0 + 4 × 1 = 9$
	となります。
4番目の星の美しさは、
	$1 × 2 + 2 × 3 + 3 × 1 + 4 × 0 = 11$
	となります。
Sample Input 2
5
123 456 789 119 1
5 2
3 1
1 2
1 4
Sample Output 2
1366
1940
1276
2616
3426

Submitted solutions:

code_snippet: // AOJ #3163
// Star Gazer 2025.1.11

#include <bits/stdc++.h>
using namespace std;

// 最大 10^5 頂点想定 (問題制約)
static const int MAXN = 100005;

// 各頂点の明るさ、部分木の明るさ合計、beauty(distSum) を格納
long long L[MAXN+1];        // brightness
long long subB[MAXN+1];     // uの部分木に含まれるすべての頂点の明るさ合計
long long distSum[MAXN+1];  // beauty(u)

// 全頂点の明るさ合計
long long sumAll = 0;

// 木の隣接リスト
vector<int> g[MAXN+1];

int N;

// dfs1: 根を 1 として、distSum[1] と subB[u] をまとめて計算
//  d は「(仮の)根1 からの深さ」 = 距離
void dfs1(int u, int parent, int depth) {
    // beauty(1) に l[u] * depth を足す
    distSum[1] += L[u] * depth;

    // 部分木の明るさを初期化
    subB[u] = L[u];

    // 子頂点へ
    for (auto &w : g[u]) {
        if (w == parent) continue;

        dfs1(w, u, depth + 1);
        subB[u] += subB[w];  // 子の部分木を親に加算
    }
}

// dfs2: 親 -> 子 で「再根付き」
//  parent = -1 はダミー (根)
void dfs2(int u, int parent) {
    // 子頂点 w について「根を u から w へ移す(再根付き)」ときの beauty(w) を計算
    for (auto &w : g[u]) {
        if (w == parent) continue;

        // 親u の beauty(u) をもとに、再根付きで beauty(w) を更新
        distSum[w] = distSum[u] + (sumAll - 2 * subB[w]);

        // 再帰的に処理
        dfs2(w, u);
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> N;
    for(int i = 1; i <= N; i++){
        cin >> L[i];
        sumAll += L[i];
    }

    // 辺の入力
    for(int i = 0; i < N - 1; i++){
        int a, b;
        cin >> a >> b;
        // 無向グラフ(=木)
        g[a].push_back(b);
        g[b].push_back(a);
    }

    // 1. dfs1 で beauty(1) と subB を計算
    dfs1(1, -1, 0);

    // 2. dfs2 で「再根付き」により distSum(beauty) を求める
    dfs2(1, -1);

    // 出力
    for(int i = 1; i <= N; i++){
        cout << distSum[i] << "\n";
    }

    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 16456
final_rank: 2

code_snippet: // competitive-verifier: PROBLEM https://onlinejudge.u-aizu.ac.jp/problems/3163
#include <cstdint>
#include <iostream>
#include <utility>
#include <vector>
/**
 * @brief 重み付きグラフ
 *
 * @tparam T 辺の重みの型
 */
template <class T>
struct Graph {
  private:
    struct _edge {
        constexpr _edge() : _from(), _to(), _weight() {}
        constexpr _edge(int from, int to, T weight) : _from(from), _to(to), _weight(weight) {}
        constexpr bool operator<(const _edge &rhs) const { return weight() < rhs.weight(); }
        constexpr bool operator>(const _edge &rhs) const { return rhs < *this; }
        constexpr int from() const { return _from; }
        constexpr int to() const { return _to; }
        constexpr T weight() const { return _weight; }
      private:
        int _from, _to;
        T _weight;
    };
  public:
    using edge_type = typename Graph<T>::_edge;
    Graph() : _size(), edges() {}
    Graph(int v) : _size(v), edges(v) {}
    const auto &operator[](int i) const { return edges[i]; }
    auto &operator[](int i) { return edges[i]; }
    const auto begin() const { return edges.begin(); }
    auto begin() { return edges.begin(); }
    const auto end() const { return edges.end(); }
    auto end() { return edges.end(); }
    constexpr int size() const { return _size; }
    void add_edge(const edge_type &e) { edges[e.from()].emplace_back(e); }
    void add_edge(int from, int to, T weight = T(1)) { edges[from].emplace_back(from, to, weight); }
    void add_edges(int from, int to, T weight = T(1)) {
        edges[from].emplace_back(from, to, weight);
        edges[to].emplace_back(to, from, weight);
    }
    void input_edge(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            T weight;
            std::cin >> from >> to >> weight;
            add_edge(from - base, to - base, weight);
        }
    }
    void input_edges(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            T weight;
            std::cin >> from >> to >> weight;
            add_edges(from - base, to - base, weight);
        }
    }
  private:
    int _size;
    std::vector<std::vector<edge_type>> edges;
};
template <>
struct Graph<void> {
  private:
    struct _edge {
        constexpr _edge() : _from(), _to() {}
        constexpr _edge(int from, int to) : _from(from), _to(to) {}
        constexpr int from() const { return _from; }
        constexpr int to() const { return _to; }
        constexpr int weight() const { return 1; }
        constexpr bool operator<(const _edge &rhs) const { return weight() < rhs.weight(); }
        constexpr bool operator>(const _edge &rhs) const { return rhs < *this; }
      private:
        int _from, _to;
    };
  public:
    using edge_type = typename Graph<void>::_edge;
    Graph() : _size(), edges() {}
    Graph(int v) : _size(v), edges(v) {}
    const auto &operator[](int i) const { return edges[i]; }
    auto &operator[](int i) { return edges[i]; }
    const auto begin() const { return edges.begin(); }
    auto begin() { return edges.begin(); }
    const auto end() const { return edges.end(); }
    auto end() { return edges.end(); }
    constexpr int size() const { return _size; }
    void add_edge(const edge_type &e) { edges[e.from()].emplace_back(e); }
    void add_edge(int from, int to) { edges[from].emplace_back(from, to); }
    void add_edges(int from, int to) {
        edges[from].emplace_back(from, to);
        edges[to].emplace_back(to, from);
    }
    void input_edge(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            std::cin >> from >> to;
            add_edge(from - base, to - base);
        }
    }
    void input_edges(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            std::cin >> from >> to;
            add_edges(from - base, to - base);
        }
    }
  private:
    int _size;
    std::vector<std::vector<edge_type>> edges;
};
/// @brief 全方位木dp
/// @see https://algo-logic.info/tree-dp/
template <class M, class T, class U>
struct ReRooting {
  private:
    using Value = typename M::value_type;
  public:
    ReRooting(const Graph<T> &g, const std::vector<U> &v)
        : graph(g), data(v), dp(g.size()), values(g.size()) {
        build();
    }
    const auto &operator[](int i) const { return values[i]; }
    auto &operator[](int i) { return values[i]; }
    const auto begin() const { return values.begin(); }
    auto begin() { return values.begin(); }
    const auto end() const { return values.end(); }
    auto end() { return values.end(); }
  private:
    Graph<T> graph;
    const std::vector<U> &data;
    std::vector<std::vector<Value>> dp;
    std::vector<Value> values;
    void build() {
        dfs(0);
        bfs(0);
    }
    Value dfs(int v, int p = -1) {
        Value res = M::id();
        int deg = graph[v].size();
        dp[v] = std::vector<Value>(deg, M::id());
        for (int i = 0; i < deg; ++i) {
            auto e = graph[v][i];
            if (e.to() == p) continue;
            dp[v][i] = M::f(dfs(e.to(), v), e.weight());
            res = M::op(res, dp[v][i]);
        }
        return M::g(res, data[v]);
    }
    void bfs(int v, int p = -1, Value dp_p = M::id()) {
        int deg = graph[v].size();
        std::vector<Value> dp_r(deg + 1, M::id());
        for (int i = deg - 1; i >= 0; --i) {
            auto e = graph[v][i];
            if (e.to() == p) dp[v][i] = M::f(dp_p, e.weight());
            dp_r[i] = M::op(dp[v][i], dp_r[i + 1]);
        }
        Value dp_l = M::id();
        for (int i = 0; i < deg; ++i) {
            int u = graph[v][i].to();
            if (u != p) bfs(u, v, M::g(M::op(dp_l, dp_r[i + 1]), data[v]));
            dp_l = M::op(dp_l, dp[v][i]);
        }
        values[v] = M::g(dp_l, v);
    }
};
struct Monoid {
    using T = std::pair<std::int64_t, std::int64_t>;
    using value_type = T;
    static constexpr T id() {
        return {0, 0};
    };
    static constexpr T op(const T &lhs, const T &rhs) {
        return {lhs.first + rhs.first, lhs.second + rhs.second};
    }
    template <class U>
    static constexpr T f(const T &v, U u) {
        return {v.first + v.second, v.second};
    }
    template <class U>
    static constexpr T g(const T &v, U u) {
        return {v.first, v.second + u};
    }
};
int main(void) {
    int n;
    std::cin >> n;
    std::vector<std::int64_t> a(n);
    for (auto &e : a) std::cin >> e;
    Graph<void> g(n);
    g.input_edges(n - 1);
    ReRooting<Monoid, void, std::int64_t> rr(g, a);
    for (int i = 0; i < n; ++i) std::cout << rr[i].first << '\n';
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 37640
final_rank: 16

code_snippet: // competitive-verifier: PROBLEM
#include <iostream>
#include <vector>
/**
 * @brief 重み付きグラフ
 *
 * @tparam T 辺の重みの型
 */
template <class T>
struct Graph {
  private:
    struct _edge {
        constexpr _edge() : _from(), _to(), _weight() {}
        constexpr _edge(int from, int to, T weight) : _from(from), _to(to), _weight(weight) {}
        constexpr bool operator<(const _edge &rhs) const { return weight() < rhs.weight(); }
        constexpr bool operator>(const _edge &rhs) const { return rhs < *this; }
        constexpr int from() const { return _from; }
        constexpr int to() const { return _to; }
        constexpr T weight() const { return _weight; }
      private:
        int _from, _to;
        T _weight;
    };
  public:
    using edge_type = typename Graph<T>::_edge;
    Graph() : _size(), edges() {}
    Graph(int v) : _size(v), edges(v) {}
    const auto &operator[](int i) const { return edges[i]; }
    auto &operator[](int i) { return edges[i]; }
    const auto begin() const { return edges.begin(); }
    auto begin() { return edges.begin(); }
    const auto end() const { return edges.end(); }
    auto end() { return edges.end(); }
    constexpr int size() const { return _size; }
    void add_edge(const edge_type &e) { edges[e.from()].emplace_back(e); }
    void add_edge(int from, int to, T weight = T(1)) { edges[from].emplace_back(from, to, weight); }
    void add_edges(int from, int to, T weight = T(1)) {
        edges[from].emplace_back(from, to, weight);
        edges[to].emplace_back(to, from, weight);
    }
    void input_edge(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            T weight;
            std::cin >> from >> to >> weight;
            add_edge(from - base, to - base, weight);
        }
    }
    void input_edges(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            T weight;
            std::cin >> from >> to >> weight;
            add_edges(from - base, to - base, weight);
        }
    }
  private:
    int _size;
    std::vector<std::vector<edge_type>> edges;
};
template <>
struct Graph<void> {
  private:
    struct _edge {
        constexpr _edge() : _from(), _to() {}
        constexpr _edge(int from, int to) : _from(from), _to(to) {}
        constexpr int from() const { return _from; }
        constexpr int to() const { return _to; }
        constexpr int weight() const { return 1; }
        constexpr bool operator<(const _edge &rhs) const { return weight() < rhs.weight(); }
        constexpr bool operator>(const _edge &rhs) const { return rhs < *this; }
      private:
        int _from, _to;
    };
  public:
    using edge_type = typename Graph<void>::_edge;
    Graph() : _size(), edges() {}
    Graph(int v) : _size(v), edges(v) {}
    const auto &operator[](int i) const { return edges[i]; }
    auto &operator[](int i) { return edges[i]; }
    const auto begin() const { return edges.begin(); }
    auto begin() { return edges.begin(); }
    const auto end() const { return edges.end(); }
    auto end() { return edges.end(); }
    constexpr int size() const { return _size; }
    void add_edge(const edge_type &e) { edges[e.from()].emplace_back(e); }
    void add_edge(int from, int to) { edges[from].emplace_back(from, to); }
    void add_edges(int from, int to) {
        edges[from].emplace_back(from, to);
        edges[to].emplace_back(to, from);
    }
    void input_edge(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            std::cin >> from >> to;
            add_edge(from - base, to - base);
        }
    }
    void input_edges(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            std::cin >> from >> to;
            add_edges(from - base, to - base);
        }
    }
  private:
    int _size;
    std::vector<std::vector<edge_type>> edges;
};
#ifdef ATCODER
#pragma GCC target("sse4.2,avx512f,avx512dq,avx512ifma,avx512cd,avx512bw,avx512vl,bmi2")
#endif
#pragma GCC optimize("Ofast,fast-math,unroll-all-loops")
#include <bits/stdc++.h>
#ifndef ATCODER
#pragma GCC target("sse4.2,avx2,bmi2")
#endif
template <class T, class U>
constexpr bool chmax(T &a, const U &b) {
    return a < (T)b ? a = (T)b, true : false;
}
template <class T, class U>
constexpr bool chmin(T &a, const U &b) {
    return (T)b < a ? a = (T)b, true : false;
}
constexpr std::int64_t INF = 1000000000000000003;
constexpr int Inf = 1000000003;
constexpr double EPS = 1e-7;
constexpr double PI = 3.14159265358979323846;
#define FOR(i, m, n) for (int i = (m); i < int(n); ++i)
#define FORR(i, m, n) for (int i = (m)-1; i >= int(n); --i)
#define FORL(i, m, n) for (int64_t i = (m); i < int64_t(n); ++i)
#define rep(i, n) FOR (i, 0, n)
#define repn(i, n) FOR (i, 1, n + 1)
#define repr(i, n) FORR (i, n, 0)
#define repnr(i, n) FORR (i, n + 1, 1)
#define all(s) (s).begin(), (s).end()
struct Sonic {
    Sonic() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(20);
    }
    constexpr void operator()() const {}
} sonic;
using namespace std;
using ll = std::int64_t;
using ld = long double;
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
    return is >> p.first >> p.second;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (T &i : v) is >> i;
    return is;
}
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
    return os << '(' << p.first << ',' << p.second << ')';
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    for (auto it = v.begin(); it != v.end(); ++it) os << (it == v.begin() ? "" : " ") << *it;
    return os;
}
template <class Head, class... Tail>
void co(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cout << head << '\n';
    else std::cout << head << ' ', co(std::forward<Tail>(tail)...);
}
template <class Head, class... Tail>
void ce(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cerr << head << '\n';
    else std::cerr << head << ' ', ce(std::forward<Tail>(tail)...);
}
void Yes(bool is_correct = true) { std::cout << (is_correct ? "Yes\n" : "No\n"); }
void No(bool is_not_correct = true) { Yes(!is_not_correct); }
void YES(bool is_correct = true) { std::cout << (is_correct ? "YES\n" : "NO\n"); }
void NO(bool is_not_correct = true) { YES(!is_not_correct); }
void Takahashi(bool is_correct = true) { std::cout << (is_correct ? "Takahashi" : "Aoki") << '\n'; }
void Aoki(bool is_not_correct = true) { Takahashi(!is_not_correct); }
/// @brief 全方位木dp
/// @see https://algo-logic.info/tree-dp/
template <class M, class T, class U>
struct ReRooting {
  private:
    using Value = typename M::value_type;
  public:
    ReRooting(const Graph<T> &g, const std::vector<U> &v)
        : graph(g), data(v), dp(g.size()), values(g.size()) {
        build();
    }
    const auto &operator[](int i) const { return values[i]; }
    auto &operator[](int i) { return values[i]; }
    const auto begin() const { return values.begin(); }
    auto begin() { return values.begin(); }
    const auto end() const { return values.end(); }
    auto end() { return values.end(); }
  private:
    Graph<T> graph;
    const std::vector<U> &data;
    std::vector<std::vector<Value>> dp;
    std::vector<Value> values;
    void build() {
        dfs(0);
        bfs(0);
    }
    Value dfs(int v, int p = -1) {
        Value res = M::id();
        int deg = graph[v].size();
        dp[v] = std::vector<Value>(deg, M::id());
        for (int i = 0; i < deg; ++i) {
            auto e = graph[v][i];
            if (e.to() == p) continue;
            dp[v][i] = M::f(dfs(e.to(), v), e.weight());
            res = M::op(res, dp[v][i]);
        }
        return M::g(res, data[v]);
    }
    void bfs(int v, int p = -1, Value dp_p = M::id()) {
        int deg = graph[v].size();
        std::vector<Value> dp_r(deg + 1, M::id());
        for (int i = deg - 1; i >= 0; --i) {
            auto e = graph[v][i];
            if (e.to() == p) dp[v][i] = M::f(dp_p, e.weight());
            dp_r[i] = M::op(dp[v][i], dp_r[i + 1]);
        }
        Value dp_l = M::id();
        for (int i = 0; i < deg; ++i) {
            int u = graph[v][i].to();
            if (u != p) bfs(u, v, M::g(M::op(dp_l, dp_r[i + 1]), data[v]));
            dp_l = M::op(dp_l, dp[v][i]);
        }
        values[v] = M::g(dp_l, v);
    }
};
struct Monoid {
    using T = pair<ll, ll>;
    using value_type = T;
    static constexpr T id() {
        return {0, 0};
    };
    static constexpr T op(const T &lhs, const T &rhs) {
        return {lhs.first + rhs.first, lhs.second + rhs.second};
    }
    template <class U>
    static constexpr T f(const T &v, U u) {
        return {v.first + v.second, v.second};
    }
    template <class U>
    static constexpr T g(const T &v, U u) {
        return {v.first, v.second + u};
    }
};
int main(void) {
    int n;
    cin >> n;
    vector<ll> a(n);
    cin >> a;
    Graph<void> g(n);
    g.input_edges(n - 1);
    ReRooting<Monoid, void, ll> rr(g, a);
    rep (i, n) co(rr[i].first);
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 37752
final_rank: 12

code_snippet: // competitive-verifier: PROBLEM
#include <iostream>
#include <vector>
/**
 * @brief 重み付きグラフ
 *
 * @tparam T 辺の重みの型
 */
template <class T>
struct Graph {
  private:
    struct _edge {
        constexpr _edge() : _from(), _to(), _weight() {}
        constexpr _edge(int from, int to, T weight) : _from(from), _to(to), _weight(weight) {}
        constexpr bool operator<(const _edge &rhs) const { return weight() < rhs.weight(); }
        constexpr bool operator>(const _edge &rhs) const { return rhs < *this; }
        constexpr int from() const { return _from; }
        constexpr int to() const { return _to; }
        constexpr T weight() const { return _weight; }
      private:
        int _from, _to;
        T _weight;
    };
  public:
    using edge_type = typename Graph<T>::_edge;
    Graph() : _size(), edges() {}
    Graph(int v) : _size(v), edges(v) {}
    const auto &operator[](int i) const { return edges[i]; }
    auto &operator[](int i) { return edges[i]; }
    const auto begin() const { return edges.begin(); }
    auto begin() { return edges.begin(); }
    const auto end() const { return edges.end(); }
    auto end() { return edges.end(); }
    constexpr int size() const { return _size; }
    void add_edge(const edge_type &e) { edges[e.from()].emplace_back(e); }
    void add_edge(int from, int to, T weight = T(1)) { edges[from].emplace_back(from, to, weight); }
    void add_edges(int from, int to, T weight = T(1)) {
        edges[from].emplace_back(from, to, weight);
        edges[to].emplace_back(to, from, weight);
    }
    void input_edge(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            T weight;
            std::cin >> from >> to >> weight;
            add_edge(from - base, to - base, weight);
        }
    }
    void input_edges(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            T weight;
            std::cin >> from >> to >> weight;
            add_edges(from - base, to - base, weight);
        }
    }
  private:
    int _size;
    std::vector<std::vector<edge_type>> edges;
};
template <>
struct Graph<void> {
  private:
    struct _edge {
        constexpr _edge() : _from(), _to() {}
        constexpr _edge(int from, int to) : _from(from), _to(to) {}
        constexpr int from() const { return _from; }
        constexpr int to() const { return _to; }
        constexpr int weight() const { return 1; }
        constexpr bool operator<(const _edge &rhs) const { return weight() < rhs.weight(); }
        constexpr bool operator>(const _edge &rhs) const { return rhs < *this; }
      private:
        int _from, _to;
    };
  public:
    using edge_type = typename Graph<void>::_edge;
    Graph() : _size(), edges() {}
    Graph(int v) : _size(v), edges(v) {}
    const auto &operator[](int i) const { return edges[i]; }
    auto &operator[](int i) { return edges[i]; }
    const auto begin() const { return edges.begin(); }
    auto begin() { return edges.begin(); }
    const auto end() const { return edges.end(); }
    auto end() { return edges.end(); }
    constexpr int size() const { return _size; }
    void add_edge(const edge_type &e) { edges[e.from()].emplace_back(e); }
    void add_edge(int from, int to) { edges[from].emplace_back(from, to); }
    void add_edges(int from, int to) {
        edges[from].emplace_back(from, to);
        edges[to].emplace_back(to, from);
    }
    void input_edge(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            std::cin >> from >> to;
            add_edge(from - base, to - base);
        }
    }
    void input_edges(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            std::cin >> from >> to;
            add_edges(from - base, to - base);
        }
    }
  private:
    int _size;
    std::vector<std::vector<edge_type>> edges;
};
#ifdef ATCODER
#pragma GCC target("sse4.2,avx512f,avx512dq,avx512ifma,avx512cd,avx512bw,avx512vl,bmi2")
#endif
#pragma GCC optimize("Ofast,fast-math,unroll-all-loops")
#include <bits/stdc++.h>
#ifndef ATCODER
#pragma GCC target("sse4.2,avx2,bmi2")
#endif
template <class T, class U>
constexpr bool chmax(T &a, const U &b) {
    return a < (T)b ? a = (T)b, true : false;
}
template <class T, class U>
constexpr bool chmin(T &a, const U &b) {
    return (T)b < a ? a = (T)b, true : false;
}
constexpr std::int64_t INF = 1000000000000000003;
constexpr int Inf = 1000000003;
constexpr double EPS = 1e-7;
constexpr double PI = 3.14159265358979323846;
#define FOR(i, m, n) for (int i = (m); i < int(n); ++i)
#define FORR(i, m, n) for (int i = (m)-1; i >= int(n); --i)
#define FORL(i, m, n) for (int64_t i = (m); i < int64_t(n); ++i)
#define rep(i, n) FOR (i, 0, n)
#define repn(i, n) FOR (i, 1, n + 1)
#define repr(i, n) FORR (i, n, 0)
#define repnr(i, n) FORR (i, n + 1, 1)
#define all(s) (s).begin(), (s).end()
struct Sonic {
    Sonic() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(20);
    }
    constexpr void operator()() const {}
} sonic;
using namespace std;
using ll = std::int64_t;
using ld = long double;
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
    return is >> p.first >> p.second;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (T &i : v) is >> i;
    return is;
}
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
    return os << '(' << p.first << ',' << p.second << ')';
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    for (auto it = v.begin(); it != v.end(); ++it) os << (it == v.begin() ? "" : " ") << *it;
    return os;
}
template <class Head, class... Tail>
void co(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cout << head << '\n';
    else std::cout << head << ' ', co(std::forward<Tail>(tail)...);
}
template <class Head, class... Tail>
void ce(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cerr << head << '\n';
    else std::cerr << head << ' ', ce(std::forward<Tail>(tail)...);
}
void Yes(bool is_correct = true) { std::cout << (is_correct ? "Yes\n" : "No\n"); }
void No(bool is_not_correct = true) { Yes(!is_not_correct); }
void YES(bool is_correct = true) { std::cout << (is_correct ? "YES\n" : "NO\n"); }
void NO(bool is_not_correct = true) { YES(!is_not_correct); }
void Takahashi(bool is_correct = true) { std::cout << (is_correct ? "Takahashi" : "Aoki") << '\n'; }
void Aoki(bool is_not_correct = true) { Takahashi(!is_not_correct); }
/**
 * @brief 全方位木dp
 * @see https://algo-logic.info/tree-dp/
 *
 * @tparam M モノイド
 * @tparam T 辺の重みの型
 */
template <class M, class U, class T>
struct ReRooting {
  private:
    using Value = typename M::value_type;
  public:
    ReRooting(const Graph<T> &g, const std::vector<U> &v)
        : graph(g), data(v), dp(g.size()), values(g.size()) {
        build();
    }
    const auto &operator[](int i) const { return values[i]; }
    auto &operator[](int i) { return values[i]; }
    const auto begin() const { return values.begin(); }
    auto begin() { return values.begin(); }
    const auto end() const { return values.end(); }
    auto end() { return values.end(); }
  private:
    Graph<T> graph;
    const std::vector<U> &data;
    std::vector<std::vector<Value>> dp;
    std::vector<Value> values;
    void build() {
        dfs(0);
        bfs(0);
    }
    Value dfs(int v, int p = -1) {
        Value res = M::id();
        int deg = graph[v].size();
        dp[v] = std::vector<Value>(deg, M::id());
        for (int i = 0; i < deg; ++i) {
            auto e = graph[v][i];
            if (e.to() == p) continue;
            dp[v][i] = M::f(dfs(e.to(), v), e.weight());
            res = M::op(res, dp[v][i]);
        }
        return M::g(res, data[v]);
    }
    void bfs(int v, int p = -1, Value dp_p = M::id()) {
        int deg = graph[v].size();
        std::vector<Value> dp_r(deg + 1, M::id());
        for (int i = deg - 1; i >= 0; --i) {
            auto e = graph[v][i];
            if (e.to() == p) dp[v][i] = M::f(dp_p, e.weight());
            dp_r[i] = M::op(dp[v][i], dp_r[i + 1]);
        }
        Value dp_l = M::id();
        for (int i = 0; i < deg; ++i) {
            int u = graph[v][i].to();
            if (u != p) bfs(u, v, M::g(M::op(dp_l, dp_r[i + 1]), data[v]));
            dp_l = M::op(dp_l, dp[v][i]);
        }
        values[v] = M::g(dp_l, v);
    }
};
struct Monoid {
    using T = pair<ll, ll>;
    using value_type = T;
    static constexpr T id() {
        return {0, 0};
    };
    static constexpr T op(const T &lhs, const T &rhs) {
        return {lhs.first + rhs.first, lhs.second + rhs.second};
    }
    template <class U>
    static constexpr T f(const T &v, U u) {
        return {v.first + v.second, v.second};
    }
    template <class U>
    static constexpr T g(const T &v, U u) {
        return {v.first, v.second + u};
    }
};
int main(void) {
    int n;
    cin >> n;
    vector<ll> a(n);
    cin >> a;
    Graph<void> g(n);
    g.input_edges(n - 1);
    ReRooting<Monoid, ll, void> rr(g, a);
    rep (i, n) co(rr[i].first);
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 37712
final_rank: 11

code_snippet: // competitive-verifier: PROBLEM
#include <iostream>
#include <vector>
/**
 * @brief 重み付きグラフ
 *
 * @tparam T 辺の重みの型
 */
template <class T>
struct Graph {
  private:
    struct _edge {
        constexpr _edge() : _from(), _to(), _weight() {}
        constexpr _edge(int from, int to, T weight) : _from(from), _to(to), _weight(weight) {}
        constexpr bool operator<(const _edge &rhs) const { return weight() < rhs.weight(); }
        constexpr bool operator>(const _edge &rhs) const { return rhs < *this; }
        constexpr int from() const { return _from; }
        constexpr int to() const { return _to; }
        constexpr T weight() const { return _weight; }
      private:
        int _from, _to;
        T _weight;
    };
  public:
    using edge_type = typename Graph<T>::_edge;
    Graph() : _size(), edges() {}
    Graph(int v) : _size(v), edges(v) {}
    const auto &operator[](int i) const { return edges[i]; }
    auto &operator[](int i) { return edges[i]; }
    const auto begin() const { return edges.begin(); }
    auto begin() { return edges.begin(); }
    const auto end() const { return edges.end(); }
    auto end() { return edges.end(); }
    constexpr int size() const { return _size; }
    void add_edge(const edge_type &e) { edges[e.from()].emplace_back(e); }
    void add_edge(int from, int to, T weight = T(1)) { edges[from].emplace_back(from, to, weight); }
    void add_edges(int from, int to, T weight = T(1)) {
        edges[from].emplace_back(from, to, weight);
        edges[to].emplace_back(to, from, weight);
    }
    void input_edge(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            T weight;
            std::cin >> from >> to >> weight;
            add_edge(from - base, to - base, weight);
        }
    }
    void input_edges(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            T weight;
            std::cin >> from >> to >> weight;
            add_edges(from - base, to - base, weight);
        }
    }
  private:
    int _size;
    std::vector<std::vector<edge_type>> edges;
};
template <>
struct Graph<void> {
  private:
    struct _edge {
        constexpr _edge() : _from(), _to() {}
        constexpr _edge(int from, int to) : _from(from), _to(to) {}
        constexpr int from() const { return _from; }
        constexpr int to() const { return _to; }
        constexpr int weight() const { return 1; }
        constexpr bool operator<(const _edge &rhs) const { return weight() < rhs.weight(); }
        constexpr bool operator>(const _edge &rhs) const { return rhs < *this; }
      private:
        int _from, _to;
    };
  public:
    using edge_type = typename Graph<void>::_edge;
    Graph() : _size(), edges() {}
    Graph(int v) : _size(v), edges(v) {}
    const auto &operator[](int i) const { return edges[i]; }
    auto &operator[](int i) { return edges[i]; }
    const auto begin() const { return edges.begin(); }
    auto begin() { return edges.begin(); }
    const auto end() const { return edges.end(); }
    auto end() { return edges.end(); }
    constexpr int size() const { return _size; }
    void add_edge(const edge_type &e) { edges[e.from()].emplace_back(e); }
    void add_edge(int from, int to) { edges[from].emplace_back(from, to); }
    void add_edges(int from, int to) {
        edges[from].emplace_back(from, to);
        edges[to].emplace_back(to, from);
    }
    void input_edge(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            std::cin >> from >> to;
            add_edge(from - base, to - base);
        }
    }
    void input_edges(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            std::cin >> from >> to;
            add_edges(from - base, to - base);
        }
    }
  private:
    int _size;
    std::vector<std::vector<edge_type>> edges;
};
#ifdef ATCODER
#pragma GCC target("sse4.2,avx512f,avx512dq,avx512ifma,avx512cd,avx512bw,avx512vl,bmi2")
#endif
#pragma GCC optimize("Ofast,fast-math,unroll-all-loops")
#include <bits/stdc++.h>
#ifndef ATCODER
#pragma GCC target("sse4.2,avx2,bmi2")
#endif
template <class T, class U>
constexpr bool chmax(T &a, const U &b) {
    return a < (T)b ? a = (T)b, true : false;
}
template <class T, class U>
constexpr bool chmin(T &a, const U &b) {
    return (T)b < a ? a = (T)b, true : false;
}
constexpr std::int64_t INF = 1000000000000000003;
constexpr int Inf = 1000000003;
constexpr double EPS = 1e-7;
constexpr double PI = 3.14159265358979323846;
#define FOR(i, m, n) for (int i = (m); i < int(n); ++i)
#define FORR(i, m, n) for (int i = (m)-1; i >= int(n); --i)
#define FORL(i, m, n) for (int64_t i = (m); i < int64_t(n); ++i)
#define rep(i, n) FOR (i, 0, n)
#define repn(i, n) FOR (i, 1, n + 1)
#define repr(i, n) FORR (i, n, 0)
#define repnr(i, n) FORR (i, n + 1, 1)
#define all(s) (s).begin(), (s).end()
struct Sonic {
    Sonic() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(20);
    }
    constexpr void operator()() const {}
} sonic;
using namespace std;
using ll = std::int64_t;
using ld = long double;
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
    return is >> p.first >> p.second;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (T &i : v) is >> i;
    return is;
}
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
    return os << '(' << p.first << ',' << p.second << ')';
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    for (auto it = v.begin(); it != v.end(); ++it) os << (it == v.begin() ? "" : " ") << *it;
    return os;
}
template <class Head, class... Tail>
void co(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cout << head << '\n';
    else std::cout << head << ' ', co(std::forward<Tail>(tail)...);
}
template <class Head, class... Tail>
void ce(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cerr << head << '\n';
    else std::cerr << head << ' ', ce(std::forward<Tail>(tail)...);
}
void Yes(bool is_correct = true) { std::cout << (is_correct ? "Yes\n" : "No\n"); }
void No(bool is_not_correct = true) { Yes(!is_not_correct); }
void YES(bool is_correct = true) { std::cout << (is_correct ? "YES\n" : "NO\n"); }
void NO(bool is_not_correct = true) { YES(!is_not_correct); }
void Takahashi(bool is_correct = true) { std::cout << (is_correct ? "Takahashi" : "Aoki") << '\n'; }
void Aoki(bool is_not_correct = true) { Takahashi(!is_not_correct); }
/**
 * @brief 全方位木dp
 * @see https://algo-logic.info/tree-dp/
 *
 * @tparam M モノイド
 * @tparam T 辺の重みの型
 */
template <class M, class U, class T>
struct ReRooting {
  private:
    using Value = typename M::value_type;
  public:
    ReRooting(const Graph<T> &g, const std::vector<U> &v)
        : graph(g), data(v), dp(g.size()), values(g.size()) {
        build();
    }
    const auto &operator[](int i) const { return values[i]; }
    auto &operator[](int i) { return values[i]; }
    const auto begin() const { return values.begin(); }
    auto begin() { return values.begin(); }
    const auto end() const { return values.end(); }
    auto end() { return values.end(); }
  private:
    Graph<T> graph;
    const std::vector<U> &data;
    std::vector<std::vector<Value>> dp;
    std::vector<Value> values;
    void build() {
        dfs(0);
        bfs(0);
    }
    Value dfs(int v, int p = -1) {
        Value res = M::id();
        int deg = graph[v].size();
        dp[v] = std::vector<Value>(deg, M::id());
        for (int i = 0; i < deg; ++i) {
            auto e = graph[v][i];
            if (e.to() == p) continue;
            dp[v][i] = M::f(dfs(e.to(), v), e.weight());
            res = M::op(res, dp[v][i]);
        }
        return M::g(res, data[v]);
    }
    void bfs(int v, int p = -1, Value dp_p = M::id()) {
        int deg = graph[v].size();
        std::vector<Value> dp_r(deg + 1, M::id());
        for (int i = deg - 1; i >= 0; --i) {
            auto e = graph[v][i];
            if (e.to() == p) dp[v][i] = M::f(dp_p, e.weight());
            dp_r[i] = M::op(dp[v][i], dp_r[i + 1]);
        }
        Value dp_l = M::id();
        for (int i = 0; i < deg; ++i) {
            int u = graph[v][i].to();
            if (u != p) bfs(u, v, M::g(M::op(dp_l, dp_r[i + 1]), data[v]));
            dp_l = M::op(dp_l, dp[v][i]);
        }
        values[v] = M::g(dp_l, v);
    }
};
struct Monoid {
    using value_type = pair<ll, ll>;
    static constexpr value_type id() {
        return {0, 0};
    };
    static constexpr value_type op(const value_type &lhs, const value_type &rhs) {
        return {lhs.first + rhs.first, lhs.second + rhs.second};
    }
    template <class T>
    static constexpr value_type f(const value_type &v, T u) {
        return {v.first + v.second, v.second};
    }
    template <class T>
    static constexpr value_type g(const value_type &v, T u) {
        return {v.first, v.second + u};
    }
};
int main(void) {
    int n;
    cin >> n;
    vector<ll> a(n);
    cin >> a;
    Graph<void> g(n);
    g.input_edges(n - 1);
    ReRooting<Monoid, ll, void> rr(g, a);
    rep (i, n) co(rr[i].first);
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 37740
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
const int INF = 1000000000;
int main() {
  int N;
  cin >> N;
  vector<int> l(N);
  for (int i = 0; i < N; i++) {
    cin >> l[i];
  }
  vector<vector<int>> E(N);
  for (int i = 0; i < N - 1; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    E[a].push_back(b);
    E[b].push_back(a);
  }
  vector<vector<int>> c(N);
  vector<int> p(N, -1);
  vector<int> bfs;
  queue<int> Q;
  Q.push(0);
  while (!Q.empty()) {
    int v = Q.front();
    Q.pop();
    bfs.push_back(v);
    for (int w : E[v]) {
      if (w != p[v]) {
        p[w] = v;
        c[v].push_back(w);
        Q.push(w);
      }
    }
  }
  reverse(bfs.begin(), bfs.end());
  vector<long long> dp1(N);//部分木のlの合計
  vector<long long> dp2(N);
  for (int v : bfs) {
    for (int w : c[v]) {
      dp1[v] += dp1[w];
      dp2[v] += dp2[w];
    }
    dp2[v] += dp1[v];
    dp1[v] += l[v];
  }
  reverse(bfs.begin(), bfs.end());
  vector<long long> dp3(N);
  dp3[0] = 0;
  for (int v : bfs) {
    long long sum = dp2[v];
    for (int w : c[v]) {
      long long sum2 = sum - dp2[w];
      sum2 -= dp1[w];
      sum2 += dp1[0] - dp1[w];
      sum2 += dp3[v];
      dp3[w] = sum2;
    }
  }
  for (int i = 0; i < N; i++) {
    cout << dp2[i] + dp3[i] << '\n';
  }
}
accuracy: 1
time_ms: 70
memory_kb: 17360
final_rank: 7

code_snippet: #include <iostream>
#include <cstdint>
#include <vector>

using namespace std;

void calc_sub(vector<uint64_t>& sub_l_sum, vector<uint64_t>& sub_beauty, const vector<vector<uint32_t>>& edges, const vector<uint32_t>& l, const uint32_t cur = 0, const uint32_t from = 0)
{
	sub_l_sum[cur] = l[cur], sub_beauty[cur] = 0;
	for (auto edge : edges[cur])
		if (edge != from)
			calc_sub(sub_l_sum, sub_beauty, edges, l, edge, cur), sub_l_sum[cur] += sub_l_sum[edge], sub_beauty[cur] += sub_beauty[edge] + sub_l_sum[edge];
}

void calc_beauty(vector<uint64_t>& beauty, const vector<uint64_t>& sub_l_sum, const vector<uint64_t>& sub_beauty, const vector<vector<uint32_t>>& edges, const uint32_t cur = 0, const uint32_t from = 0)
{
	if (cur == 0) beauty[0] = sub_beauty[0];
	else beauty[cur] = beauty[from] + sub_l_sum[0] - sub_l_sum[cur] * 2;

	for (auto edge : edges[cur])
		if (edge != from)
			calc_beauty(beauty, sub_l_sum, sub_beauty, edges, edge, cur);
}

int main()
{
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	uint32_t N, i;
	cin >> N;
	vector<uint32_t> l(N), a(N - 1), b(N - 1);
	for (i = 0; i != N; ++i)
		cin >> l[i];
	for (i = 0; i != N - 1; ++i)
		cin >> a[i] >> b[i];

	vector<vector<uint32_t>> edges(N, vector<uint32_t>());
	vector<uint64_t> sub_l_sum(N), sub_beauty(N), beauty(N);
	for (i = 0; i != N - 1; ++i)
		edges[a[i] - 1].push_back(b[i] - 1), edges[b[i] - 1].push_back(a[i] - 1);

	calc_sub(sub_l_sum, sub_beauty, edges, l);
	calc_beauty(beauty, sub_l_sum, sub_beauty, edges);
	
	for (i = 0; i != N; ++i) cout << beauty[i] << '\n';
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 19848
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define repd(i,a,b) for (ll i=(a);i<(b);i++)
#define rep(i,n) repd(i,0,n)
#define all(x) (x).begin(),(x).end()
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
typedef long long ll;
typedef pair<ll,ll> P;
typedef vector<ll> vec;
using Graph = vector<vector<ll>>;
const long long INF = 1LL<<60;
const long long MOD = 1000000007;

//https://nyaannyaan.github.io/library/graph/graph-template.hpp
template <typename T>
struct edge {
  int src, to;
  T cost;

  edge(int _to, T _cost) : src(-1), to(_to), cost(_cost) {}
  edge(int _src, int _to, T _cost) : src(_src), to(_to), cost(_cost) {}

  edge &operator=(const int &x) {
    to = x;
    return *this;
  }

  operator int() const { return to; }
};
template <typename T>
using Edges = vector<edge<T>>;
template <typename T>
using WeightedGraph = vector<Edges<T>>;
using UnweightedGraph = vector<vector<int>>;

// Input of (Unweighted) Graph
UnweightedGraph graph(int N, int M = -1, bool is_directed = false,
                      bool is_1origin = true) {
  UnweightedGraph g(N);
  if (M == -1) M = N - 1;
  for (int _ = 0; _ < M; _++) {
    int x, y;
    cin >> x >> y;
    if (is_1origin) x--, y--;
    g[x].push_back(y);
    if (!is_directed) g[y].push_back(x);
  }
  return g;
}

// Input of Weighted Graph
template <typename T>
WeightedGraph<T> wgraph(int N, int M = -1, bool is_directed = false,
                        bool is_1origin = true) {
  WeightedGraph<T> g(N);
  if (M == -1) M = N - 1;
  for (int _ = 0; _ < M; _++) {
    int x, y;
    cin >> x >> y;
    T c;
    cin >> c;
    if (is_1origin) x--, y--;
    g[x].emplace_back(x, y, c);
    if (!is_directed) g[y].emplace_back(y, x, c);
  }
  return g;
}

// Input of Edges
template <typename T>
Edges<T> esgraph(int N, int M, int is_weighted = true, bool is_1origin = true) {
  Edges<T> es;
  for (int _ = 0; _ < M; _++) {
    int x, y;
    cin >> x >> y;
    T c;
    if (is_weighted)
      cin >> c;
    else
      c = 1;
    if (is_1origin) x--, y--;
    es.emplace_back(x, y, c);
  }
  return es;
}

// Input of Adjacency Matrix
template <typename T>
vector<vector<T>> adjgraph(int N, int M, T INF, int is_weighted = true,
                           bool is_directed = false, bool is_1origin = true) {
  vector<vector<T>> d(N, vector<T>(N, INF));
  for (int _ = 0; _ < M; _++) {
    int x, y;
    cin >> x >> y;
    T c;
    if (is_weighted)
      cin >> c;
    else
      c = 1;
    if (is_1origin) x--, y--;
    d[x][y] = c;
    if (!is_directed) d[y][x] = c;
  }
  return d;
}

/**
 * @brief グラフテンプレート
 * @docs docs/graph/graph-template.md
 */

//https://nyaannyaan.github.io/library/tree/rerooting.hpp

// Rerooting
// f1(c1, c2) ... merge value of child node
// f2(memo[i], chd, par) ... return value from child node to parent node
// memo[i] ... result of subtree rooted i
// dp[i] ... result of tree rooted i
template <typename T, typename G, typename F1, typename F2>
struct Rerooting {
  const G &g;
  const F1 f1;
  const F2 f2;
  vector<T> memo, dp;
  T I;

  Rerooting(const G &_g, const F1 _f1, const F2 _f2, const T &I_)
      : g(_g), f1(_f1), f2(_f2), memo(g.size(), I_), dp(g.size(), I_), I(I_) {
    dfs(0, -1);
    efs(0, -1, I);
  }

  const T &operator[](int i) const { return dp[i]; }

  void dfs(int cur, int par) {
    for (auto &dst : g[cur]) {
      if (dst == par) continue;
      dfs(dst, cur);
      memo[cur] = f1(memo[cur], f2(memo[dst], dst, cur));
    }
  }

  void efs(int cur, int par, const T &pval) {
    // get cumulative sum
    vector<T> buf;
    for (auto dst : g[cur]) {
      if (dst == par) continue;
      buf.push_back(f2(memo[dst], dst, cur));
    }
    vector<T> head(buf.size() + 1), tail(buf.size() + 1);
    head[0] = tail[buf.size()] = I;
    for (int i = 0; i < (int)buf.size(); i++) head[i + 1] = f1(head[i], buf[i]);
    for (int i = (int)buf.size() - 1; i >= 0; i--)
      tail[i] = f1(tail[i + 1], buf[i]);

    // update
    dp[cur] = par == -1 ? head.back() : f1(pval, head.back());

    // propagate
    int idx = 0;
    for (auto &dst : g[cur]) {
      if (dst == par) continue;
      efs(dst, cur, f2(f1(pval, f1(head[idx], tail[idx + 1])), cur, dst));
      idx++;
    }
  }
};

/**
 * @brief Rerooting(全方位木DP)
 * @docs docs/tree/rerooting.md
 */

// auto mod int
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
const int mod = 1000000007;
struct mint {
  ll x; // typedef long long ll;
  mint(ll x=0):x((x%mod+mod)%mod){}
  mint operator-() const { return mint(-x);}
  mint& operator+=(const mint a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator-=(const mint a) {
    if ((x += mod-a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator*=(const mint a) { (x *= a.x) %= mod; return *this;}
  mint operator+(const mint a) const { return mint(*this) += a;}
  mint operator-(const mint a) const { return mint(*this) -= a;}
  mint operator*(const mint a) const { return mint(*this) *= a;}
  mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t>>1);
    a *= a;
    if (t&1) a *= *this;
    return a;
  }

  // for prime mod
  mint inv() const { return pow(mod-2);}
  mint& operator/=(const mint a) { return *this *= a.inv();}
  mint operator/(const mint a) const { return mint(*this) /= a;}
};
istream& operator>>(istream& is, mint& a) { return is >> a.x;}
ostream& operator<<(ostream& os, const mint& a) { return os << a.x;}

// combination mod prime
// https://www.youtube.com/watch?v=8uowVvQ_-Mo&feature=youtu.be&t=1619
struct combination {
  vector<mint> fact, ifact;
  combination(int n):fact(n+1),ifact(n+1) {
    assert(n < mod);
    fact[0] = 1;
    for (int i = 1; i <= n; ++i) fact[i] = fact[i-1]*i;
    ifact[n] = fact[n].inv();
    for (int i = n; i >= 1; --i) ifact[i-1] = ifact[i]*i;
  }
  mint operator()(int n, int k) {
    if (k < 0 || k > n) return 0;
    return fact[n]*ifact[k]*ifact[n-k];
  }
  mint p(int n,int k){
      return fact[n]*ifact[n-k];
  }
} C(1000005);

using F=tuple<ll,ll>;

int main()
{  
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll n;cin>>n;
    vec l(n);
    rep(i,n)cin>>l[i];
    auto g=graph(n,n-1,0,1);
    auto f1=[&](F x,F y){
      auto[a,b]=x;
      auto[c,d]=y;
      a+=c;
      b+=d;
      return F(a,b);
    };
    auto f2=[&](F x,int ch,int p){
      auto[a,b]=x;
      b+=l[ch];
      a+=b;
      return F(a,b);
    };
    Rerooting<F,decltype(g),decltype(f1),decltype(f2)> dp(g,f1,f2,{0,0});
    for(auto ans:dp.dp){
      cout<<get<0>(ans)<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 51160
final_rank: 18

code_snippet: /* -*- coding: utf-8 -*-
 *
 * 3163.cc: Problem M: Star Gazer
 */

#include<cstdio>
#include<vector>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_N = 100000;

/* typedef */

typedef long long ll;
typedef vector<int> vi;

/* global variables */

int ls[MAX_N], ps[MAX_N], cis[MAX_N];
vi nbrs[MAX_N];
ll lss[MAX_N], dp[MAX_N], pdp[MAX_N];

/* subroutines */

/* main */

int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) scanf("%d", ls + i);

  for (int i = 1; i < n; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    u--, v--;
    nbrs[u].push_back(v);
    nbrs[v].push_back(u);
  }

  ps[0] = -1;
  for (int u = 0; u >= 0;) {
    vi &nbru = nbrs[u];
    int up = ps[u];

    if (cis[u] < nbru.size()) {
      int v = nbru[cis[u]++];
      if (v != up) {
	ps[v] = u;
	u = v;
      }
    }
    else {
      lss[u] += ls[u];

      if (up >= 0) {
	lss[up] += lss[u];
	dp[up] += dp[u] + lss[u];
      }

      u = up;
    }
  }
  //for (int u = 0; u < n; u++) printf("%lld ", dp[u]); putchar('\n');

  fill(cis, cis + n, 0);
  pdp[0] = 0;
  for (int u = 0; u >= 0;) {
    vi &nbru = nbrs[u];
    int up = ps[u];

    if (cis[u] < nbru.size()) {
      int v = nbru[cis[u]++];
      if (v != up) {
	pdp[v] = (dp[u] + pdp[u]) - (dp[v] + lss[v]) + (lss[0] - lss[v]);
	u = v;
      }
    }
    else
      u = up;
  }

  for (int u = 0; u < n; u++) printf("%lld\n", dp[u] + pdp[u]);

  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 12032
final_rank: 1

code_snippet: #include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <vector>
#include <numeric>
#include <algorithm>
#include <queue>
#include <string>
#include <random>
#include <array>
#include <climits>
#include <map>
#include <cassert>
#include <stack>
#include <iomanip>
#include <cfloat>
#include <fstream>


int main() {
	int n; std::cin >> n;
	std::vector<int> brightness(n);
	for (auto& l : brightness) {
		std::cin >> l;
	}
	std::vector<std::pair<int, int>> edges(n - 1);
	for (auto& [a, b] : edges) {
		std::cin >> a >> b; --a; --b;
	}
	std::vector<std::vector<int>> graph(n);
	for (const auto [a, b] : edges) {
		graph[a].push_back(b);
		graph[b].push_back(a);
	}
	std::vector<int> depth(n, -1);
	std::stack<int> stack;
	std::vector<int> history;
	depth[0] = 0;
	stack.push(0);
	while (!stack.empty()) {
		const auto top = stack.top(); stack.pop();
		history.push_back(top);
		for (const auto next : graph[top]) {
			if (depth[next] != -1) continue;
			depth[next] = depth[top] + 1;
			stack.push(next);
		}
	}
	std::vector<long long int> sum_brightness(n), from_leaf(n, 0);
	std::copy(brightness.begin(), brightness.end(), sum_brightness.begin());
	std::reverse(history.begin(), history.end());
	for (const auto node : history) {
		for (const auto child : graph[node]) {
			if (depth[child] < depth[node]) continue;
			sum_brightness[node] += sum_brightness[child];
			from_leaf[node] += from_leaf[child] + sum_brightness[child];
		}
	}
	std::vector<long long int> from_root(n, 0);
	std::reverse(history.begin(), history.end());
	for (const auto node : history) {
		for (const auto child : graph[node]) {
			if (depth[child] < depth[node]) continue;
			from_root[child] = from_root[node] + (from_leaf[node] - from_leaf[child] - sum_brightness[child]) + (sum_brightness[0] - sum_brightness[child]);
		}
	}
	for (auto i = 0; i < n; ++i) {
		std::cout << from_leaf[i] + from_root[i] << '\n';
	}
}
accuracy: 1
time_ms: 60
memory_kb: 13780
final_rank: 4

code_snippet: #ifdef LOCAL
    #define _GLIBCXX_DEBUG
    #define __clock__
#else
    #pragma GCC optimize("Ofast")
#endif
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using VI = vector<ll>;
using VV = vector<VI>;
using VS = vector<string>;
using PII = pair<ll, ll>;

// #define INT128 // 必要なら有効化してください
#ifdef INT128
  using LL = __int128;
#endif

// tourist set
template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s) {
  return '"' + s + '"';
}

string to_string(const char* s) {
  return to_string((string) s);
}

string to_string(bool b) {
  return (b ? "true" : "false");
}

string to_string(char c){
  string s = {c};
  return s;
}

// LL
#ifdef INT128
// input
istream& operator>>(istream& is, LL& v)
{
    string s;
    is >> s;
    v = 0;
    for (int i = 0; i < (int)s.size(); i++) {
        if (isdigit(s[i])) { v = v * 10 + s[i] - '0'; }
    }
    if (s[0] == '-') { v *= -1; }
    return is;
}
std::ostream &operator<<(std::ostream &dest, LL value) {
  std::ostream::sentry s(dest);
  if (s) {
    LL tmp = value < 0 ? -value : value;
    char buffer[128];
    char *d = std::end(buffer);
    do {
      --d;
      *d = "0123456789"[tmp % 10];
      tmp /= 10;
    } while (tmp != 0);
    if (value < 0) {
      --d;
      *d = '-';
    }
    int len = std::end(buffer) - d;
    if (dest.rdbuf()->sputn(d, len) != len) {
      dest.setstate(std::ios_base::badbit);
    }
  }
  return dest;
}
string to_string(LL v){
  stringstream ss;
  ss << v;
  return ss.str();
}
#endif // LL

string to_string(vector<bool> v) {
  bool first = true;
  string res = "{";
  for (int i = 0; i < static_cast<int>(v.size()); i++) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(v[i]);
  }
  res += "}";
  return res;
}

template <size_t N>
string to_string(bitset<N> v) {
  string res = "";
  for (size_t i = 0; i < N; i++) {
    res += static_cast<char>('0' + v[i]);
  }
  return res;
}

template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

void debug_out() { cerr << '\n'; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}

#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif
// tourist set end

template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }

#define FOR(i,a,b) for(ll i=(a);i<(b);++i)
#define rep(i,b) FOR(i, 0, b)
#define ALL(v) (v).begin(), (v).end()
#define p(s) cout<<(s)<<'\n'
#define p2(s, t) cout << (s) << " " << (t) << '\n'
#define SZ(x) ((int)(x).size())
#define SORT(A) sort(ALL(A))
#define RSORT(A) sort(ALL(A), greater<ll>())
#define MP make_pair
#define p_yes() p("Yes")
#define p_no() p("No")
#define p_possible() p("Possible")
#define p_impossible() p("Impossible")
void yes(){p_yes(); exit(0);}
void no(){p_no(); exit(0);}
void possible(){p_possible(); exit(0);}
void impossible(){p_impossible(); exit(0);}

ll SUM(VI& V){
  return accumulate(ALL(V), 0LL);
}

ll MIN(VI& V){return *min_element(ALL(V));}
ll MAX(VI& V){return *max_element(ALL(V));}

void print_vector(VI& V, ll offset=0){
  ll n = V.size();
  rep(i, n){
    if(i) cout << ' ';
    cout << V[i]+offset;
  }
  cout << endl;
}

ll gcd(ll a,ll b){
    if(b == 0) return a;
    return gcd(b,a%b);
}

ll lcm(ll a,ll b){
    ll g = gcd(a,b);
    return a / g * b;
}

// long double
using ld = long double;
// #define EPS (1e-14)
constexpr ld EPS = 1e-14;
// #define equals(a,b) (fabs((a)-(b)) < EPS)
constexpr bool equals(ld a, ld b){return fabs((a)-(b)) < EPS;}

// 小さい順に取り出すpriority queue
using inverse_priority_queue = priority_queue<ll, vector<ll>, greater<ll> >;

int popcount(ll t){
    return __builtin_popcountll(t);
}

const ll mod = 1e9 + 7;
// const ll mod = 998244353;
const ll inf = 4e18; // LLONG_MAX = 9223372036854775807 (atcoder, codeforces)
const double PI = acos(-1);

// [a/b] (繰り上げ)
ll ceil_div(ll a, ll b){
  return (a+b-1)/b;
}

ll ll_pow(ll a, ll n){
    ll ans = 1;
    FOR(i, 0, n){
        ans *= a;
    }
    return ans;
}
// modなし

// snuke's mint
// auto mod int
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
// const int mod = 1000000007;
struct mint {
  ll x; // using ll = long long;
  mint(ll x=0):x((x%mod+mod)%mod){}
  mint operator-() const { return mint(-x);}
  mint& operator+=(const mint a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator-=(const mint a) {
    if ((x += mod-a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint a) const {
    mint res(*this);
    return res+=a;
  }
  mint operator-(const mint a) const {
    mint res(*this);
    return res-=a;
  }
  mint operator*(const mint a) const {
    mint res(*this);
    return res*=a;
  }
  mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t>>1);
    a *= a;
    if (t&1) a *= *this;
    return a;
  }

  // for prime mod
  mint inv() const {
    return pow(mod-2);
  }
  mint& operator/=(const mint a) {
    return (*this) *= a.inv();
  }
  mint operator/(const mint a) const {
    mint res(*this);
    return res/=a;
  }
};

// ※双方向
// N : 頂点数
// M : 辺数
// return vector<vector<ll>>
VV load_graph(ll N, ll M){
  VV G(N);
  rep(i,M){
    ll a,b;cin>>a>>b;
    a--;b--;
    G[a].push_back(b);
    G[b].push_back(a);
  }
  return G;
}
VV load_tree(ll N){
  return load_graph(N, N-1);
}

VI loadV(ll N){
  VI A(N);
  rep(i,N)cin>>A[i];
  return A;
}

//#include <atcoder/dsu>
//using namespace atcoder; // 忘れがち


int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);

    // input
    ll N;cin>>N;
    VI L = loadV(N); // light
    ll sumL = SUM(L);

    VV G(N);
    rep(i,N-1){
      ll a,b;cin>>a>>b;
      a--;b--;
      G[a].push_back(b);
      G[b].push_back(a);
    }

    VI parent(N,-1); // parent

    // light of subtree
    VI dpL(N);
    function<ll(ll,ll)> dfs2 = [&](ll i, ll prev){
      parent[i]=prev;
      ll sum=L[i];
      for(ll to : G[i]){
        if(to==prev)continue;
        sum += dfs2(to,i);
      }
      return dpL[i]=sum;
    };
    dfs2(0,-1);
    debug(dpL);

    // answer of subtree
    VI dp(N);
    function<ll(ll,ll)> dfs = [&](ll i, ll prev){
      ll sum=0;
      for(ll to : G[i]){
        if(to==prev)continue;
        sum += dfs(to,i) + dpL[to];
      }
      return dp[i]=sum;
    };
    dfs(0,-1);
    
    function<void(ll,ll)> bfs = [&](ll i, ll prev){
      // prevには全方向が入っている
      
      // 自分のdpを求めて
      ll otherlight = sumL - dpL[i];

      ll add = dp[prev]-dp[i]-dpL[i]+otherlight;
      dp[i]+=add;

      // 子へ
      for(ll to : G[i]){
        if(to==prev)continue;
        bfs(to,i);
      }
    };
    for(ll to : G[0]){
      bfs(to,0);
    }

    rep(i,N){
      p(dp[i]);
    }

    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 19368
final_rank: 5

code_snippet: #line 2 "/home/yuruhiya/programming/library/template/template.cpp"
#include <bits/stdc++.h>
#line 4 "/home/yuruhiya/programming/library/template/constants.cpp"
#include <string_view>
#line 7 "/home/yuruhiya/programming/library/template/constants.cpp"

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define rrep(i, n) for (int i = (n)-1; i >= 0; --i)
#define rfor(i, m, n) for (int i = (m); i >= (n); --i)
#define unless(c) if (!(c))
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define range_it(a, l, r) (a).begin() + (l), (a).begin() + (r)

using namespace std;
using ll = long long;
using LD = long double;
using VB = vector<bool>;
using VVB = vector<VB>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;
using VS = vector<string>;
using VD = vector<LD>;
using PII = pair<int, int>;
using VP = vector<PII>;
using PLL = pair<ll, ll>;
using VPL = vector<PLL>;
template <class T> using PQ = priority_queue<T>;
template <class T> using PQS = priority_queue<T, vector<T>, greater<T>>;
constexpr int inf = 1000000000;
constexpr long long inf_ll = 1000000000000000000ll, MOD = 1000000007;
constexpr long double PI = 3.14159265358979323846, EPS = 1e-12;
namespace CharacterClass {
	constexpr string_view
	    digit = "0123456789",
	    xdigit = "0123456789ABCDEFabcdef", lower = "abcdefghijklmnopqrstuvwxyz",
	    upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
	    alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
	    alnum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
	    word = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz",
	    punct = R"(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)",
	    graph =
	        R"(!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~)",
	    print =
	        R"( !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~)",
	    blank = " \t", space = " \t\n\r\f\v";
}  // namespace CharacterClass
#line 7 "/home/yuruhiya/programming/library/template/Input.cpp"
using namespace std;

#ifdef _WIN32
#define getchar_unlocked _getchar_nolock
#define putchar_unlocked _putchar_nolock
#define fwrite_unlocked fwrite
#define fflush_unlocked fflush
#endif
class Scanner {
	static int gc() {
		return getchar_unlocked();
	}
	static char next_char() {
		char c;
		read(c);
		return c;
	}
	template <class T> static void read(T& v) {
		cin >> v;
	}
	static void read(char& v) {
		while (isspace(v = gc()))
			;
	}
	static void read(bool& v) {
		v = next_char() != '0';
	}
	static void read(string& v) {
		v.clear();
		for (char c = next_char(); !isspace(c); c = gc()) v += c;
	}
	static void read(int& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(long long& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(double& v) {
		v = 0;
		double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	static void read(long double& v) {
		v = 0;
		long double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	template <class T, class U> static void read(pair<T, U>& v) {
		read(v.first);
		read(v.second);
	}
	template <class T> static void read(vector<T>& v) {
		for (auto& e : v) read(e);
	}
	template <size_t N = 0, class T> static void read_tuple_impl(T& v) {
		if constexpr (N < tuple_size_v<T>) {
			read(get<N>(v));
			read_tuple_impl<N + 1>(v);
		}
	}
	template <class... T> static void read(tuple<T...>& v) {
		read_tuple_impl(v);
	}
	struct ReadVectorHelper {
		size_t n;
		ReadVectorHelper(size_t _n) : n(_n) {}
		template <class T> operator vector<T>() {
			vector<T> v(n);
			read(v);
			return v;
		}
	};
	struct Read2DVectorHelper {
		size_t n, m;
		Read2DVectorHelper(const pair<size_t, size_t>& nm) : n(nm.first), m(nm.second) {}
		template <class T> operator vector<vector<T>>() {
			vector<vector<T>> v(n, vector<T>(m));
			read(v);
			return v;
		}
	};

public:
	string read_line() const {
		string v;
		for (char c = gc(); c != '\n' && c != '\0'; c = gc()) v += c;
		return v;
	}
	template <class T> T read() const {
		T v;
		read(v);
		return v;
	}
	template <class T> vector<T> read_vector(size_t n) const {
		vector<T> a(n);
		read(a);
		return a;
	}
	template <class T> operator T() const {
		return read<T>();
	}
	int operator--(int) const {
		return read<int>() - 1;
	}
	ReadVectorHelper operator[](size_t n) const {
		return ReadVectorHelper(n);
	}
	Read2DVectorHelper operator[](const pair<size_t, size_t>& nm) const {
		return Read2DVectorHelper(nm);
	}
	void operator()() const {}
	template <class H, class... T> void operator()(H&& h, T&&... t) const {
		read(h);
		operator()(forward<T>(t)...);
	}

private:
	template <template <class...> class, class...> struct Multiple;
	template <template <class...> class V, class Head, class... Tail>
	struct Multiple<V, Head, Tail...> {
		template <class... Args> using vec = V<vector<Head>, Args...>;
		using type = typename Multiple<vec, Tail...>::type;
	};
	template <template <class...> class V> struct Multiple<V> { using type = V<>; };
	template <class... T> using multiple_t = typename Multiple<tuple, T...>::type;
	template <size_t N = 0, class T> void multiple_impl(T& t) const {
		if constexpr (N < tuple_size_v<T>) {
			auto& vec = get<N>(t);
			using V = typename remove_reference_t<decltype(vec)>::value_type;
			vec.push_back(read<V>());
			multiple_impl<N + 1>(t);
		}
	}

public:
	template <class... T> auto multiple(size_t h) const {
		multiple_t<T...> result;
		while (h--) multiple_impl(result);
		return result;
	}
} in;
#define inputs(T, ...) \
	T __VA_ARGS__;     \
	in(__VA_ARGS__)
#define ini(...) inputs(int, __VA_ARGS__)
#define inl(...) inputs(long long, __VA_ARGS__)
#define ins(...) inputs(string, __VA_ARGS__)
#line 7 "/home/yuruhiya/programming/library/template/Output.cpp"
#include <charconv>
#line 10 "/home/yuruhiya/programming/library/template/Output.cpp"
using namespace std;

struct BoolStr {
	const char *t, *f;
	BoolStr(const char* _t, const char* _f) : t(_t), f(_f) {}
} Yes("Yes", "No"), yes("yes", "no"), YES("YES", "NO"), Int("1", "0");
struct DivStr {
	const char *d, *l;
	DivStr(const char* _d, const char* _l) : d(_d), l(_l) {}
} spc(" ", "\n"), no_spc("", "\n"), end_line("\n", "\n"), comma(",", "\n"),
    no_endl(" ", "");
class Printer {
	BoolStr B{Yes};
	DivStr D{spc};

public:
	void print(int v) const {
		char buf[12]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void print(long long v) const {
		char buf[21]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void print(bool v) const {
		print(v ? B.t : B.f);
	}
	void print(vector<bool>::reference v) const {
		print(v ? B.t : B.f);
	}
	void print(char v) const {
		putchar_unlocked(v);
	}
	void print(const char* v) const {
		fwrite_unlocked(v, 1, strlen(v), stdout);
	}
	void print(double v) const {
		printf("%.20f", v);
	}
	void print(long double v) const {
		printf("%.20Lf", v);
	}
	template <class T> void print(const T& v) const {
		cout << v;
	}
	template <class T, class U> void print(const pair<T, U>& v) const {
		print(v.first);
		print(D.d);
		print(v.second);
	}
	template <class InputIterater>
	void print_range(const InputIterater& begin, const InputIterater& end) const {
		for (InputIterater i = begin; i != end; ++i) {
			if (i != begin) print(D.d);
			print(*i);
		}
	}
	template <class T> void print(const vector<T>& v) const {
		print_range(v.begin(), v.end());
	}
	template <class T, size_t N> void print(const array<T, N>& v) const {
		print_range(v.begin(), v.end());
	}
	template <class T> void print(const vector<vector<T>>& v) const {
		for (size_t i = 0; i < v.size(); ++i) {
			if (i) print(D.l);
			print(v[i]);
		}
	}

	Printer() = default;
	Printer(const BoolStr& _boolstr, const DivStr& _divstr) : B(_boolstr), D(_divstr) {}
	Printer& operator()() {
		print(D.l);
		return *this;
	}
	template <class H> Printer& operator()(H&& h) {
		print(h);
		print(D.l);
		return *this;
	}
	template <class H, class... T> Printer& operator()(H&& h, T&&... t) {
		print(h);
		print(D.d);
		return operator()(forward<T>(t)...);
	}
	template <class InputIterator>
	Printer& range(const InputIterator& begin, const InputIterator& end) {
		print_range(begin, end);
		print(D.l);
		return *this;
	}
	template <class T> Printer& range(const T& a) {
		range(a.begin(), a.end());
		return *this;
	}
	template <class... T> void exit(T&&... t) {
		operator()(forward<T>(t)...);
		std::exit(EXIT_SUCCESS);
	}
	Printer& flush() {
		fflush_unlocked(stdout);
		return *this;
	}
	Printer& set(const BoolStr& b) {
		B = b;
		return *this;
	}
	Printer& set(const DivStr& d) {
		D = d;
		return *this;
	}
	Printer& set(const char* t, const char* f) {
		B = BoolStr(t, f);
		return *this;
	}
} out;
#line 3 "/home/yuruhiya/programming/library/template/Step.cpp"
using namespace std;

template <class T> struct Step {
	using value_type = T;

	class iterator {
		value_type a, b, c;

	public:
		constexpr iterator() : a(value_type()), b(value_type()), c(value_type()) {}
		constexpr iterator(value_type _b, value_type _c, value_type _s)
		    : a(_b), b(_c), c(_s) {}
		constexpr iterator& operator++() {
			--b;
			a += c;
			return *this;
		}
		constexpr iterator operator++(int) {
			iterator tmp = *this;
			--b;
			a += c;
			return tmp;
		}
		constexpr const value_type& operator*() const {
			return a;
		}
		constexpr const value_type* operator->() const {
			return &a;
		}
		constexpr bool operator==(const iterator& i) const {
			return b == i.b;
		}
		constexpr bool operator!=(const iterator& i) const {
			return !(b == i.b);
		}
		constexpr value_type start() const {
			return a;
		}
		constexpr value_type size() const {
			return b;
		}
		constexpr value_type step() const {
			return c;
		}
	};
	constexpr Step(value_type b, value_type c, value_type s) : be(b, c, s) {}
	constexpr iterator begin() const {
		return be;
	}
	constexpr iterator end() const {
		return en;
	}
	constexpr value_type start() const {
		return be.start();
	}
	constexpr value_type size() const {
		return be.size();
	}
	constexpr value_type step() const {
		return be.step();
	}
	constexpr value_type sum() const {
		return start() * size() + step() * (size() * (size() - 1) / 2);
	}
	operator vector<value_type>() const {
		return to_a();
	}
	auto to_a() const {
		vector<value_type> result;
		result.reserve(size());
		for (auto i : *this) {
			result.push_back(i);
		}
		return result;
	}

private:
	iterator be, en;
};
template <class T> constexpr auto step(T a) {
	return Step<T>(0, a, 1);
}
template <class T> constexpr auto step(T a, T b) {
	return Step<T>(a, b - a, 1);
}
template <class T> constexpr auto step(T a, T b, T c) {
	return Step<T>(a, a < b ? (b - a - 1) / c + 1 : 0, c);
}
#line 8 "/home/yuruhiya/programming/library/template/Ruby.cpp"
using namespace std;

template <class F> struct Callable {
	F func;
	Callable(const F& f) : func(f) {}
};
template <class T, class F> auto operator|(const T& v, const Callable<F>& c) {
	return c.func(v);
}

struct Sort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const Sort_impl& c) {
		sort(begin(v), end(v));
		return v;
	}
} Sort;
struct SortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) < f(j); });
			return v;
		});
	}
} SortBy;
struct RSort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(rbegin(v), rend(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const RSort_impl& c) {
		sort(rbegin(v), rend(v));
		return v;
	}
} RSort;
struct RSortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) > f(j); });
			return v;
		});
	}
} RSortBy;
struct Reverse_impl {
	template <class T> friend auto operator|(T v, const Reverse_impl& c) {
		reverse(begin(v), end(v));
		return v;
	}
} Reverse;
struct Unique_impl {
	template <class T> friend auto operator|(T v, const Unique_impl& c) {
		v.erase(unique(begin(v), end(v), end(v)));
		return v;
	}
} Unique;
struct Uniq_impl {
	template <class T> friend auto operator|(T v, const Uniq_impl& c) {
		sort(begin(v), end(v));
		v.erase(unique(begin(v), end(v)), end(v));
		return v;
	}
} Uniq;
struct Rotate_impl {
	auto operator()(int&& left) {
		return Callable([&](auto v) {
			int s = static_cast<int>(size(v));
			assert(-s <= left && left <= s);
			if (0 <= left) {
				rotate(begin(v), begin(v) + left, end(v));
			} else {
				rotate(begin(v), end(v) + left, end(v));
			}
			return v;
		});
	}
} Rotate;
struct Max_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *max_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Max_impl& c) {
		return *max_element(begin(v), end(v));
	}
} Max;
struct Min_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *min_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Min_impl& c) {
		return *min_element(begin(v), end(v));
	}
} Min;
struct MaxPos_impl {
	template <class T> friend auto operator|(T v, const MaxPos_impl& c) {
		return max_element(begin(v), end(v)) - begin(v);
	}
} MaxPos;
struct MinPos_impl {
	template <class T> friend auto operator|(T v, const MinPos_impl& c) {
		return min_element(begin(v), end(v)) - begin(v);
	}
} MinPos;
struct MaxBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_it = begin(v);
			auto max_val = f(*max_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_it = it;
					max_val = val;
				}
			}
			return *max_it;
		});
	}
} MaxBy;
struct MinBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_it = begin(v);
			auto min_val = f(*min_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_it = it;
					min_val = val;
				}
			}
			return *min_it;
		});
	}
} MinBy;
struct MaxOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_val = val;
				}
			}
			return max_val;
		});
	}
} MaxOf;
struct MinOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_val = val;
				}
			}
			return min_val;
		});
	}
} MinOf;
struct Count_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return count(begin(v), end(v), val); });
	}
} Count;
struct CountIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return count_if(begin(v), end(v), f); });
	}
} CountIf;
struct Index_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find(begin(v), end(v), val);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
	template <class V> auto operator()(const V& val, size_t i) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find(next(begin(v), i), end(v), val);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} Index;
struct IndexIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} IndexIf;
struct FindIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<typename decltype(v)::value_type> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(*result) : nullopt;
		});
	}
} FindIf;
struct Sum_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			return accumulate(next(begin(v)), end(v), f(*begin(v)),
			                  [&](const auto& a, const auto& b) { return a + f(b); });
		});
	}
	template <class T> friend auto operator|(T v, const Sum_impl& c) {
		return accumulate(begin(v), end(v), typename T::value_type{});
	}
} Sum;
struct Includes {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return find(begin(v), end(v), val) != end(v); });
	}
} Includes;
struct IncludesIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return find_if(begin(v), end(v), f) != end(v); });
	}
} IncludesIf;
struct RemoveIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) {
			v.erase(remove_if(begin(v), end(v), f), end(v));
			return v;
		});
	}
} RemoveIf;
struct Each_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				f(i);
			}
		});
	}
} Each;
struct Select_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using value_type = typename decltype(v)::value_type;
			vector<value_type> result;
			for (const auto& i : v) {
				if (f(i)) result.push_back(i);
			}
			return result;
		});
	}
} Select;
struct Map_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using result_type = invoke_result_t<F, typename decltype(v)::value_type>;
			vector<result_type> result;
			result.reserve(size(v));
			for (const auto& i : v) {
				result.push_back(f(i));
			}
			return result;
		});
	}
} Map;
struct Indexed_impl {
	template <class T> friend auto operator|(const T& v, Indexed_impl& c) {
		using value_type = typename T::value_type;
		vector<pair<value_type, int>> result;
		result.reserve(size(v));
		int index = 0;
		for (const auto& i : v) {
			result.emplace_back(i, index++);
		}
		return result;
	}
} Indexed;
struct AllOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (!f(i)) return false;
			}
			return true;
		});
	}
} AllOf;
struct AnyOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return true;
			}
			return false;
		});
	}
} AnyOf;
struct NoneOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return false;
			}
			return true;
		});
	}
} NoneOf;

struct Tally_impl {
	template <class F> auto operator()(size_t max_val) {
		return Callable([&](auto v) {
			vector<size_t> result(max_val);
			for (const auto& i : v) {
				result[static_cast<size_t>(i)]++;
			}
			return result;
		});
	}
	template <class T, class value_type = typename T::value_type>
	friend auto operator|(const T& v, Tally_impl& c) {
		map<value_type, size_t> result;
		for (const auto& i : v) {
			result[i]++;
		}
		return result;
	}
} Tally;

template <class T> auto operator*(const vector<T>& a, size_t n) {
	T result;
	for (size_t i = 0; i < n; ++i) {
		result.insert(result.end(), a.begin(), a.end());
	}
	return result;
}
auto operator*(string a, size_t n) {
	string result;
	for (size_t i = 0; i < n; ++i) {
		result += a;
	}
	return result;
}
template <class T, class U> auto& operator<<(vector<T>& a, const U& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T> auto& operator<<(string& a, const T& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T, class U> auto operator+(vector<T> a, const U& b) {
	a << b;
	return a;
}
template <class T> auto operator+(string a, const T& b) {
	a << b;
	return a;
}
#line 7 "/home/yuruhiya/programming/library/template/functions.cpp"
using namespace std;

template <class T = long long> constexpr T TEN(size_t n) {
	T result = 1;
	for (size_t i = 0; i < n; ++i) result *= 10;
	return result;
}
template <class T, class U,
          enable_if_t<is_integral_v<T> && is_integral_v<U>, nullptr_t> = nullptr>
constexpr auto div_ceil(T n, U m) {
	return (n + m - 1) / m;
}
template <class T, class U> constexpr auto div_ceil2(T n, U m) {
	return div_ceil(n, m) * m;
}
template <class T> constexpr T triangle(T n) {
	return (n & 1) ? (n + 1) / 2 * n : n / 2 * (n + 1);
}
template <class T> constexpr T nC2(T n) {
	return (n & 1) ? (n - 1) / 2 * n : n / 2 * (n - 1);
}
template <class T, class U> constexpr auto middle(const T& l, const U& r) {
	return l + (r - l) / 2;
}
template <class T, class U, class V>
constexpr bool in_range(const T& v, const U& lower, const V& upper) {
	return lower <= v && v < upper;
}
template <class T, enable_if_t<is_integral_v<T>, nullptr_t> = nullptr>
constexpr bool is_square(T n) {
	T s = sqrt(n);
	return s * s == n || (s + 1) * (s + 1) == n;
}
template <class T = long long> constexpr T BIT(int b) {
	return T(1) << b;
}
template <class T> constexpr int BIT(T x, int i) {
	return (x & (1 << i)) ? 1 : 0;
}
template <class T, class U, enable_if_t<is_integral_v<U>, nullptr_t> = nullptr>
constexpr T Pow(T a, U n) {
	assert(n >= 0);
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result *= a;
			n--;
		} else {
			a *= a;
			n >>= 1;
		}
	}
	return result;
}
template <class T, class U, enable_if_t<is_integral_v<U>, nullptr_t> = nullptr>
constexpr T Powmod(T a, U n, T mod) {
	assert(n >= 0);
	if (a > mod) a %= mod;
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result = result * a % mod;
			n--;
		} else {
			a = a * a % mod;
			n >>= 1;
		}
	}
	return result;
}
template <class T> bool chmax(T& a, const T& b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool chmin(T& a, const T& b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> int sz(const T& v) {
	return v.size();
}
template <class T, class U> int lower_index(const T& a, const U& v) {
	return lower_bound(all(a), v) - a.begin();
}
template <class T, class U> int upper_index(const T& a, const U& v) {
	return upper_bound(all(a), v) - a.begin();
}
template <class T> auto Slice(const T& v, size_t i, size_t len) {
	return i < v.size() ? T(v.begin() + i, v.begin() + min(i + len, v.size())) : T();
}
template <class T, class U = typename T::value_type> U Gcdv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), gcd<U, U>);
}
template <class T, class U = typename T::value_type> U Lcmv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), lcm<U, U>);
}
namespace internal {
	template <class T, size_t N> auto make_vector(vector<int>& sizes, const T& init) {
		if constexpr (N == 1) {
			return vector(sizes[0], init);
		} else {
			int size = sizes[N - 1];
			sizes.pop_back();
			return vector(size, make_vector<T, N - 1>(sizes, init));
		}
	}
}  // namespace internal
template <class T, size_t N>
auto make_vector(const int (&sizes)[N], const T& init = T()) {
	vector s(rbegin(sizes), rend(sizes));
	return internal::make_vector<T, N>(s, init);
}
#line 9 "/home/yuruhiya/programming/library/template/template.cpp"
#if __has_include(<library/dump.hpp>)
#include <library/dump.hpp>
#define LOCAL
#else
#define dump(...) ((void)0)
#endif

template <class T> constexpr T oj_local(const T& oj, const T& local) {
#ifndef LOCAL
	return oj;
#else
	return local;
#endif
}
#line 3 "/home/yuruhiya/programming/library/Graph/ReRooting.cpp"
using namespace std;

template <class DP> class ReRooting {
	int n;
	vector<vector<int>> graph;
	vector<vector<DP>> dp;
	vector<DP> ans;

	DP dfs(int v, int p) {
		DP sum;
		for (size_t i = 0; i < graph[v].size(); ++i) {
			int e = graph[v][i];
			DP& dp_e = dp[v][i];
			if (e != p) {
				dp_e = dfs(e, v);
				sum += dp_e;
			}
		}
		return sum.add_root(v);
	}
	void bfs(int v, int p, const DP& dp_par) {
		for (size_t i = 0; i < graph[v].size(); ++i) {
			if (graph[v][i] == p) {
				dp[v][i] = dp_par;
			}
		}

		vector<DP> dp_left(graph[v].size() + 1);
		for (size_t i = 0; i < graph[v].size(); ++i) {
			dp_left[i + 1] = dp_left[i] + dp[v][i];
		}
		vector<DP> dp_right(graph[v].size() + 1);
		for (int i = graph[v].size() - 1; i >= 0; --i) {
			dp_right[i] = dp_right[i + 1] + dp[v][i];
		}
		ans[v] = dp_left.back().add_root(v);

		for (size_t i = 0; i < graph[v].size(); ++i) {
			int e = graph[v][i];
			if (e != p) {
				bfs(e, v, (dp_left[i] + dp_right[i + 1]).add_root(v));
			}
		}
	}

public:
	ReRooting(const vector<vector<int>>& _graph) : n(_graph.size()), graph(_graph), dp(n), ans(n) {
		for (int i = 0; i < n; ++i) dp[i].resize(graph[i].size());
	}
	vector<DP> solve() {
		dfs(0, -1);
		bfs(0, -1, DP());
		return ans;
	}
};

/*
struct DP {
    int dp;
    DP(int _dp = 1) : dp(_dp) {}
    DP operator+(const DP& d) const {
        return DP(*this) += d;
    }
    DP& operator+=(const DP& d) {
        return *this;
    }
    DP add_root([[maybe_unused]] int v) const {
        DP res = *this;

        return res;
    }
};
*/
#line 3 "a.cpp"

VL a;

struct DP {
	ll sum, val;
	DP() : sum(0), val(0) {}
	DP operator+(const DP& d) const {
		return DP(*this) += d;
	}
	DP& operator+=(const DP& d) {
		sum += d.sum;
		val += d.val;
		return *this;
	}
	DP add_root([[maybe_unused]] int v) const {
		DP res = *this;
		res.val += sum;
		res.sum += a[v];
		return res;
	}
};

int main() {
	ini(n);
	a = in[n];
	VVI g(n);
	rep(i, n - 1) {
		int u = in--, v = in--;
		g[u].push_back(v);
		g[v].push_back(u);
	}

	ReRooting<DP> dp(g);
	auto ans = dp.solve();
	rep(i, n) out(ans[i].val);
}
accuracy: 1
time_ms: 50
memory_kb: 43232
final_rank: 13

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 9223372036854775807
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 100005

int N,root;
ll total_L;
ll dp[SIZE],L[SIZE],sum_L[SIZE];
ll ans[SIZE];
vector<int> G[SIZE];

void dfs(int node_id,int pre){

	sum_L[node_id] += L[node_id];

	for(int i = 0; i < G[node_id].size(); i++){

		int next = G[node_id][i];
		if(next == pre)continue;

		dfs(next,node_id);
		dp[node_id] += dp[next]+sum_L[next];
		sum_L[node_id] += sum_L[next];
	}
}

void dfs2(int node_id,int pre){

	if(node_id == root){

		ans[root] = dp[root];
	}else{

		ans[node_id] = dp[node_id]+(ans[pre]-(dp[node_id]+sum_L[node_id]))+total_L-sum_L[node_id];
	}

	for(int i = 0; i < G[node_id].size(); i++){

		int next = G[node_id][i];
		if(next == pre)continue;

		dfs2(next,node_id);
	}
}


int main(){

	scanf("%d",&N);

	total_L = 0;

	for(int i = 0; i < N; i++){

		scanf("%lld",&L[i]);
		total_L += L[i];
	}

	int from,to;

	for(int i = 0; i < N-1; i++){

		scanf("%d %d",&from,&to);
		from--;
		to--;

		G[from].push_back(to);
		G[to].push_back(from);
	}

	for(int i = 0; i < N; i++){

		dp[i] = 0;
		sum_L[i] = 0;
	}

	root = 0;

	dfs(root,-1);
	dfs2(root,-1);

	for(int i = 0; i < N; i++){

		printf("%lld\n",ans[i]);
	}

	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 17152
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define REP(i,n) for(ll i=0;i<(ll)n;i++)
#define dump(x)  cerr << "Line " << __LINE__ << ": " <<  #x << " = " << (x) << "\n";
#define spa << " " <<
#define fi first
#define se second
#define ALL(a)  (a).begin(),(a).end()
#define ALLR(a)  (a).rbegin(),(a).rend()

using ld = long double;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<ld, ld>;

template<typename T> using V = vector<T>;
template<typename T> using P = pair<T, T>;
template<typename T> vector<T> make_vec(size_t n, T a) { return vector<T>(n, a); }
template<typename... Ts> auto make_vec(size_t n, Ts... ts) { return vector<decltype(make_vec(ts...))>(n, make_vec(ts...)); }
template<class S, class T> ostream& operator << (ostream& os, const pair<S, T> v){os << "(" << v.first << ", " << v.second << ")"; return os;}
template<typename T> ostream& operator<<(ostream &os, const vector<T> &v) { for (auto &e : v) os << e << ' '; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<vector<T>> &v){ for(auto &e : v){os << e << "\n";} return os;}
struct fast_ios { fast_ios(){ cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;

template <class T> void UNIQUE(vector<T> &x) {sort(ALL(x));x.erase(unique(ALL(x)), x.end());}
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
void fail() { cout << -1 << '\n'; exit(0); }
inline int popcount(const int x) { return __builtin_popcount(x); }
inline int popcount(const ll x) { return __builtin_popcountll(x); }
template<typename T> void debug(vector<vector<T>>&v,ll h,ll w){for(ll i=0;i<h;i++)
{cerr<<v[i][0];for(ll j=1;j<w;j++)cerr spa v[i][j];cerr<<"\n";}};
template<typename T> void debug(vector<T>&v,ll n){if(n!=0)cerr<<v[0];
for(ll i=1;i<n;i++)cerr spa v[i];
cerr<<"\n";};

const ll INF = (1ll<<62);
// const ld EPS   = 1e-10;
// const ld PI    = acos(-1.0);
const ll mod = (int)1e9 + 7;
//const ll mod = 998244353;

template< typename sum_t, typename key_t >
struct ReRooting {
  struct Edge {
    int to;
    key_t data;
    sum_t dp, ndp;
  };

  using F = function< sum_t(sum_t, sum_t) >;
  using G = function< sum_t(sum_t, key_t) >;

  // subdp: 一度目のdfsの結果を保持する配列
  // dp: 二度目のdfsの後，結果を各頂点でマージした値を保持する配列
  vector< vector< Edge > > g;
  const F f;
  const G gg;
  const sum_t ident;
  vector< sum_t > subdp, dp;

  ReRooting(int V, const F f, const G g, const sum_t &ident)
      : g(V), f(f), gg(g), ident(ident), subdp(V, ident), dp(V, ident) {}

  // add_edge は危険なので使わない方が良い
  // u->v に重み d の有向辺を追加するのではなく，
  // u->v と v->u の両方に重み d の有向辺を追加する
  // void add_edge(int u, int v, const key_t &d) {
  //   g[u].emplace_back((Edge) {v, d, ident, ident});
  //   g[v].emplace_back((Edge) {u, d, ident, ident});
  // }

  // u->v に重み d の有向辺を追加し，
  // v->u に重み e の有向辺を追加する
  void add_edge_bi(int u, int v, const key_t &d, const key_t &e) {
    g[u].emplace_back((Edge) {v, d, ident, ident});
    g[v].emplace_back((Edge) {u, e, ident, ident});
  }

  // 一度目のdfs
  void dfs_sub(int idx, int par) {
    for(auto &e : g[idx]) {
      if(e.to == par) continue;
      dfs_sub(e.to, idx);
      subdp[idx] = f(subdp[idx], gg(subdp[e.to], e.data));
    }
  }

  // 二度目のdfs
  void dfs_all(int idx, int par, const sum_t &top) {
    sum_t buff{ident};
    for(int i = 0; i < (int) g[idx].size(); i++) {
      auto &e = g[idx][i];
      e.ndp = buff;
      e.dp = gg(par == e.to ? top : subdp[e.to], e.data);
      buff = f(buff, e.dp);
    }
    dp[idx] = buff;
    buff = ident;
    for(int i = (int) g[idx].size() - 1; i >= 0; i--) {
      auto &e = g[idx][i];
      if(e.to != par) dfs_all(e.to, idx, f(e.ndp, buff));
      e.ndp = f(e.ndp, buff);
      buff = f(buff, e.dp);
    }
  }

  vector< sum_t > build() {
    dfs_sub(0, -1);
    dfs_all(0, -1, ident);
    return dp;
  }
};

int main(){

    ll N;
    cin >> N;
    V<ll> l(N);
    REP(i, N) cin >> l[i];

    auto f1 = [](pll x, pll y){
        return pll{x.first+y.first, x.second+y.second};
    };

    auto f2 = [](pll x, ll a){
        return pll{x.first+a, x.first+x.second+a};
    };

    ReRooting<pll, ll> RR(N, f1, f2, pll{0, 0});

    REP(i, N-1){
        ll a, b;
        cin >> a >> b;
        a--, b--;
        RR.add_edge_bi(a, b, l[b], l[a]);
    }
    RR.build();

    REP(i, N) cout << RR.dp[i].second << "\n";


    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 44264
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using LL = long long int;
#define incII(i, l, r) for(LL i = (l)    ; i <= (r); i++)
#define incIX(i, l, r) for(LL i = (l)    ; i <  (r); i++)
#define incXI(i, l, r) for(LL i = (l) + 1; i <= (r); i++)
#define incXX(i, l, r) for(LL i = (l) + 1; i <  (r); i++)
#define decII(i, l, r) for(LL i = (r)    ; i >= (l); i--)
#define decIX(i, l, r) for(LL i = (r) - 1; i >= (l); i--)
#define decXI(i, l, r) for(LL i = (r)    ; i >  (l); i--)
#define decXX(i, l, r) for(LL i = (r) - 1; i >  (l); i--)
#define inc(i, n)  incIX(i, 0, n)
#define dec(i, n)  decIX(i, 0, n)
#define inc1(i, n) incII(i, 1, n)
#define dec1(i, n) decII(i, 1, n)
auto inII = [](auto x, auto l, auto r) { return (l <= x && x <= r); };
auto inIX = [](auto x, auto l, auto r) { return (l <= x && x <  r); };
auto inXI = [](auto x, auto l, auto r) { return (l <  x && x <= r); };
auto inXX = [](auto x, auto l, auto r) { return (l <  x && x <  r); };
auto setmin   = [](auto & a, auto b) { return (b <  a ? a = b, true : false); };
auto setmax   = [](auto & a, auto b) { return (b >  a ? a = b, true : false); };
auto setmineq = [](auto & a, auto b) { return (b <= a ? a = b, true : false); };
auto setmaxeq = [](auto & a, auto b) { return (b >= a ? a = b, true : false); };
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define MT make_tuple
#define FI first
#define SE second
#define FR front()
#define BA back()
#define ALL(c) c.begin(), c.end()
#define RALL(c) c.rbegin(), c.rend()
#define RV(c) reverse(ALL(c))
#define SC static_cast
#define SI(c) SC<int>(c.size())
#define SL(c) SC<LL >(c.size())
#define RF(e, c) for(auto & e: c)
#define SF(c, ...) for(auto & [__VA_ARGS__]: c)
#define until(e) while(! (e))
#define if_not(e) if(! (e))
#define ef else if
#define UR assert(false)
auto * IS = & cin;
auto * OS = & cout;
array<string, 3> SEQ = { "", " ", "" };
// input
template<typename T> T in() { T a; (* IS) >> a; return a; }
// input: tuple
template<int I, typename U> void tin_(istream & is, U & t) {
	if constexpr(I < tuple_size<U>::value) { is >> get<I>(t); tin_<I + 1>(is, t); }
}
template<typename ... T> istream & operator>>(istream & is, tuple<T ...> & t) { tin_<0>(is, t); return is; }
template<typename ... T> auto tin() { return in<tuple<T ...>>(); }
// input: array
template<typename T, size_t N> istream & operator>>(istream & is, array<T, N> & a) { RF(e, a) { is >> e; } return is; }
template<typename T, size_t N> auto ain() { return in<array<T, N>>(); }
// input: multi-dimensional vector
template<typename T> T vin() { T v; (* IS) >> v; return v; }
template<typename T, typename N, typename ... M> auto vin(N n, M ... m) {
	vector<decltype(vin<T, M ...>(m ...))> v(n); inc(i, n) { v[i] = vin<T, M ...>(m ...); } return v;
}
// input: multi-column (tuple<vector>)
template<typename U, int I> void colin_([[maybe_unused]] U & t) { }
template<typename U, int I, typename A, typename ... B> void colin_(U & t) {
	get<I>(t).PB(in<A>()); colin_<U, I + 1, B ...>(t);
}
template<typename ... T> auto colin(int n) {
	tuple<vector<T> ...> t; inc(i, n) { colin_<tuple<vector<T> ...>, 0, T ...>(t); } return t;
}
// output
void out_([[maybe_unused]] string s) { }
template<typename A> void out_([[maybe_unused]] string s, A && a) { (* OS) << a; }
template<typename A, typename ... B> void out_(string s, A && a, B && ... b) { (* OS) << a << s; out_(s, b ...); }
auto outF = [](auto x, auto y, auto z, auto ... a) { (* OS) << x; out_(y, a ...); (* OS) << z << flush; };
auto out  = [](auto ... a) { outF("", " " , "\n", a ...); };
auto outS = [](auto ... a) { outF("", " " , " " , a ...); };
auto outL = [](auto ... a) { outF("", "\n", "\n", a ...); };
auto outN = [](auto ... a) { outF("", ""  , ""  , a ...); };
// output: multi-dimensional vector
template<typename T> ostream & operator<<(ostream & os, vector<T> const & v) {
	os << SEQ[0]; inc(i, SI(v)) { os << (i == 0 ? "" : SEQ[1]) << v[i]; } return (os << SEQ[2]);
}
template<typename T> void vout_(T && v) { (* OS) << v; }
template<typename T, typename A, typename ... B> void vout_(T && v, A a, B ... b) {
	inc(i, SI(v)) { (* OS) << (i == 0 ? "" : a); vout_(v[i], b ...); }
}
template<typename T, typename A, typename ... B> void vout (T && v, A a, B ... b) { vout_(v, a, b ...); (* OS) << a << flush; }
template<typename T, typename A, typename ... B> void voutN(T && v, A a, B ... b) { vout_(v, a, b ...); (* OS)      << flush; }

// ---- ----

int main() {
	auto n = in<int>();
	auto l = vin<LL>(n);
	vector<vector<int>> g(n);
	inc(i, n - 1) {
		auto [a, b] = ain<int, 2>();
		a--; b--;
		g[a].PB(b);
		g[b].PB(a);
	}
	
	vector<LL> s(n), ans(n);
	function<void(int, int, int)> dfs = [&](int t, int v, int p) {
		if(t == 0) {
			RF(e, g[v]) {
				if(e == p) { continue; }
				dfs(t, e, v);
				l[v] += l[e];
				s[v] += l[e] + s[e];
			}
		} else {
			if(v == 0) {
				ans[v] = s[v];
			} else {
				ans[v] = ans[p] + l[0] - 2 * l[v]; 
			}
			RF(e, g[v]) {
				if(e == p) { continue; }
				dfs(t, e, v);
			}
		}
	};
	dfs(0, 0, -1);
	dfs(1, 0, -1);
	vout(ans, "\n");
}
accuracy: 1
time_ms: 70
memory_kb: 20124
final_rank: 8

code_snippet: //#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
//#include <atcoder/all>
//using namespace atcoder;
using ll = long long;
#define pp pair<int,int>
#define rep(i,n) for(int (i)=0;(i)<(n);(i)++)
#define ld long double
#define al(a) (a).begin(),(a).end()
#define mk make_pair
#define check cout<<"?"<<endl;

ll MOD=1000000007;
ll mod=998244353;
int inf=1000001000;
ll INF=1e18+5;

template<typename T>
ostream& operator<<(ostream& os,const vector<T>& v){
    if(v.empty()){
        os<<"{ }";
        return os;
    }
    os<<"{"<<v.front();
    for(auto itr=++v.begin();itr!=v.end();itr++){
        os<<", "<<*itr;
    }
    os<<"}";
    return os;
}

template<typename T_first,typename T_second>
ostream& operator<<(ostream& os,const pair<T_first,T_second>& P){
    os<<"("<<P.first;
    os<<", "<<P.second;
    os<<")";
    return os;
}

struct edge{
    int from;
    int to;
    int idx;
    int rev;
    edge(int from=-1,int to=-1,int idx=-1,int rev=-1):to(to),rev(rev){}
};

template<class DP>
class ReRooting{
public:

    using E=function<DP()>; 
    using F=function<DP(DP,DP)>;
    using F_=function<DP(edge,DP)>;
    int n;
    vector<vector<edge>> path;
    vector<vector<DP>> edges_dp;
    E e;
    vector<DP> res;
    F merge;
    F_ mapping;

    ReRooting(int n,E e,F merge,F_ mapping):n(n),e(e),merge(merge),mapping(mapping){
        res.assign(n,e());
        path.assign(n,vector<edge>(0));
        edges_dp.assign(n,vector<DP>(0));
    }

    void add_edge(int from,int to){
        path[from].push_back(edge{from,to,(int)path[from].size(),(int)path[to].size()});
        path[to].push_back(edge{to,from,(int)path[to].size(),(int)path[from].size()-1});
        edges_dp[from].push_back(e());
        edges_dp[to].push_back(e());
    }

    void solve(){
        dfs(0,-1,-1);
        bfs(0);
    }

    DP dfs(int s,int p,int idx){
        if(s==0){
            rep(i,(int)path[s].size()){
                dfs(path[s][i].to,s,i);
            }
            return DP{};
        }

        DP& cur_edge=edges_dp[p][idx];
        rep(i,(int)path[s].size()){
            if(path[s][i].to==p) continue;
            cur_edge=merge(cur_edge,dfs(path[s][i].to,s,i));
        }
        cur_edge=mapping(path[p][idx],cur_edge);

        return cur_edge;
    }

    void bfs(int start){
        vector<bool> visited(n,false);
        queue<int> que;
        que.push(start);
        while(!que.empty()){
            int s=que.front();
            que.pop();
            int degree=(int)path[s].size();
            vector<DP> merge_left(degree,e());
            vector<DP> merge_right(degree,e());
            for(int i=1;i<degree;i++){
                merge_left[i]=merge(edges_dp[s][i-1],merge_left[i-1]);
            }
            for(int i=degree-2;i>=0;i--){
                merge_right[i]=merge(edges_dp[s][i+1],merge_right[i+1]);
            }
            rep(i,degree){
                if(visited[path[s][i].to]) continue;
                edge& cur_edge=path[s][i];
                edges_dp[cur_edge.to][cur_edge.rev]=merge(edges_dp[cur_edge.to][cur_edge.rev],merge_left[i]);
                edges_dp[cur_edge.to][cur_edge.rev]=merge(edges_dp[cur_edge.to][cur_edge.rev],merge_right[i]);
                edges_dp[cur_edge.to][cur_edge.rev]=mapping(path[cur_edge.to][cur_edge.rev],edges_dp[cur_edge.to][cur_edge.rev]);
                que.push(cur_edge.to);
            }
            res[s]=merge(edges_dp[s][0],merge_right[0]);
            visited[s]=true;
        }
    }
};

vector<ll> l;

//using DP=intなども可
struct DP{
    ll dp;
    ll sum;
};
DP e(){
    return DP{0,0}; 
}
//モノイド
DP dp_merge(DP p,DP a){
    p.dp=p.dp+a.dp;
    p.sum=p.sum+a.sum;
    return p;
}
DP mapping(edge cur_edge,DP x){
    x.sum=x.sum+l[cur_edge.to];
    x.dp=x.dp+x.sum;
    return x;
}

int main(){
    int n; cin>>n;
    l.assign(n,0);
    rep(i,n) cin>>l[i];
    ReRooting<DP> tdp(n,e,dp_merge,mapping);
    rep(i,n-1){
        int a,b; cin>>a>>b;
        tdp.add_edge(a-1,b-1);
    }
    tdp.solve();
    rep(i,n) printf("%lld\n",tdp.res[i].dp);
}
accuracy: 1
time_ms: 100
memory_kb: 33408
final_rank: 14

code_snippet: //#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
//#include <atcoder/all>
//using namespace atcoder;
using ll = long long;
#define pp pair<int,int>
#define rep(i,n) for(int (i)=0;(i)<(n);(i)++)
#define ld long double
#define al(a) (a).begin(),(a).end()
#define mk make_pair
#define check cout<<"?"<<endl;

ll MOD=1000000007;
ll mod=998244353;
int inf=1000001000;
ll INF=1e18+5;

template<typename T>
ostream& operator<<(ostream& os,const vector<T>& v){
    if(v.empty()){
        os<<"{ }";
        return os;
    }
    os<<"{"<<v.front();
    for(auto itr=++v.begin();itr!=v.end();itr++){
        os<<", "<<*itr;
    }
    os<<"}";
    return os;
}

template<typename T_first,typename T_second>
ostream& operator<<(ostream& os,const pair<T_first,T_second>& P){
    os<<"("<<P.first;
    os<<", "<<P.second;
    os<<")";
    return os;
}

template<class DP>
class ReRooting{
public:
    struct edge{
        int to;
        int rev;
        edge(int to=-1,int rev=-1):to(to),rev(rev){}
    };

    using E=function<DP(int)>; 
    using F=function<DP(DP,DP)>;
    using F_=function<DP(DP)>;
    int n;
    vector<vector<edge>> path;
    vector<vector<DP>> edges_dp;
    E e;
    vector<DP> res;
    F merge;
    F_ mapping;

    ReRooting(int n,E e,F merge,F_ mapping):n(n),e(e),merge(merge),mapping(mapping){
        res.assign(n,e(-1));
        path.assign(n,vector<edge>(0));
        edges_dp.assign(n,vector<DP>(0));
    }

    void add_edge(int from,int to){
        path[from].push_back(edge{to,(int)path[to].size()});
        path[to].push_back(edge{from,(int)path[from].size()-1});
        edges_dp[from].push_back(e(to));
        edges_dp[to].push_back(e(from));
    }

    void solve(){
        dfs(0,-1,-1);
        bfs(0);
    }

    DP dfs(int s,int p,int idx){
        if(s==0){
            rep(i,(int)path[s].size()){
                dfs(path[s][i].to,s,i);
            }
            return DP{};
        }

        DP& cur_edge=edges_dp[p][idx];
        rep(i,(int)path[s].size()){
            if(path[s][i].to==p) continue;
            cur_edge=merge(cur_edge,dfs(path[s][i].to,s,i));
        }
        cur_edge=mapping(cur_edge);

        return cur_edge;
    }

    void bfs(int start){
        vector<bool> visited(n,false);
        queue<int> que;
        que.push(start);
        while(!que.empty()){
            int s=que.front();
            que.pop();
            int degree=(int)path[s].size();
            vector<DP> merge_left(degree,e(-1));
            vector<DP> merge_right(degree,e(-1));
            for(int i=1;i<degree;i++){
                merge_left[i]=merge(edges_dp[s][i-1],merge_left[i-1]);
            }
            for(int i=degree-2;i>=0;i--){
                merge_right[i]=merge(edges_dp[s][i+1],merge_right[i+1]);
            }
            rep(i,degree){
                if(visited[path[s][i].to]) continue;
                edge& cur_edge=path[s][i];
                edges_dp[cur_edge.to][cur_edge.rev]=merge(edges_dp[cur_edge.to][cur_edge.rev],merge_left[i]);
                edges_dp[cur_edge.to][cur_edge.rev]=merge(edges_dp[cur_edge.to][cur_edge.rev],merge_right[i]);
                edges_dp[cur_edge.to][cur_edge.rev]=mapping(edges_dp[cur_edge.to][cur_edge.rev]);
                que.push(cur_edge.to);
            }
            res[s]=merge(edges_dp[s][0],merge_right[0]);
            visited[s]=true;
        }
    }
};

vector<ll> l;

//using DP=intなども可
struct DP{
    int to;
    ll dp;
    ll sum;
};
DP e(int to=-1){
    return DP{to,0,0}; 
}
DP dp_merge(DP p,DP a){
    p.dp=p.dp+a.dp;
    p.sum=p.sum+a.sum;
    return p;
}
DP mapping(DP x){
    x.sum=x.sum+l[x.to];
    x.dp=x.dp+x.sum;
    return x;
}

int main(){
    int n; cin>>n;
    l.assign(n,0);
    rep(i,n) cin>>l[i];
    ReRooting<DP> tdp(n,e,dp_merge,mapping);
    rep(i,n-1){
        int a,b; cin>>a>>b;
        tdp.add_edge(a-1,b-1);
    }
    tdp.solve();
    rep(i,n) printf("%lld\n",tdp.res[i].dp);
}
accuracy: 1
time_ms: 110
memory_kb: 40836
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;

//////////////////////////////   Begin Macros

#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define in(x, a, b) (a <= x and x < b)
#define rep(i, N) for (int i = 0; i < (int)(N); i++)
#define reprev(i, N) for (int i = (int)(N)-1; i >= 0; i--)
#define rep1(i, N) for (int i = 1; i <= (int)(N); i++)
#define rep1rev(i, N) for (int i = (int)(N); i >= 0; i--)
#define forbe(i, b, e) for (int i = (b); i < (e); i++)
#define forberev(i, b, e) for (int i = (e)-1; i >= (b); i--)
#define forfl(i, f, l) for (int i = (f); i <= (l); i++)
#define forflrev(i, f, l) for (int i = (l); i >= (f); i--)
using ll = long long;
using pii = pair<int, int>;
using pil = pair<int, ll>;
using pli = pair<ll, int>;
using pll = pair<ll, ll>;

template <typename T>
bool chmax(T &m, const T q)
{
  if (m < q)
  {
    m = q;
    return true;
  }
  else
    return false;
}
template <typename T>
bool chmin(T &m, const T q)
{
  if (m > q)
  {
    m = q;
    return true;
  }
  else
    return false;
}
template <typename T1, typename T2>
pair<T1, T2> operator+(const pair<T1, T2> &l, const pair<T1, T2> &r) { return {l.first + r.first, l.second + r.second}; }
template <typename T1, typename T2>
pair<T1, T2> operator-(const pair<T1, T2> &l, const pair<T1, T2> &r) { return {l.first - r.first, l.second - r.second}; }
template <typename T>
pair<T, T> operator*(const pair<T, T> &l, const T &r) { return {l.first * r, l.second * r}; }
template <typename T>
pair<T, T> operator/(const pair<T, T> &l, const T &r) { return {l.first / r, l.second / r}; }
template <typename T>
istream &operator>>(istream &is, vector<T> &vec)
{
  for (auto &v : vec)
    is >> v;
  return is;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &vec)
{
  os << "[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const deque<T> &vec)
{
  os << "deq[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const set<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_set<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const multiset<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_multiset<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &pa)
{
  is >> pa.first >> pa.second;
  return is;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &pa)
{
  os << "(" << pa.first << "," << pa.second << ")";
  return os;
}
template <typename... Ts>
istream &operator>>(istream &is, tuple<Ts...> &theTuple)
{
  apply([&is](Ts &... tupleArgs) { ((is >> tupleArgs), ...); }, theTuple);
  return is;
}
template <typename... Ts>
ostream &operator<<(ostream &os, const tuple<Ts...> &theTuple)
{
  apply([&os](const Ts &... tupleArgs) {
    os << '(';
    size_t n(0);
    ((os << tupleArgs << (++n < sizeof...(Ts) ? "," : "")), ...);
    os << ')';
  },
        theTuple);
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const map<TK, TV> &mp)
{
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp)
{
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}

template <typename T>
void reset(vector<T> &v, const T reset_to)
{
  for (auto &x : v)
    x = reset_to;
}
inline int popcount(const unsigned int x) { return __builtin_popcount(x); }
#define dbg(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;

ll nC2(ll n)
{
  return n * (n - 1) / 2;
}

const int intinf = numeric_limits<int>::max();
const ll llinf = numeric_limits<ll>::max();
const pii udlr[4] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

//////////////////////////////   End Macros

// Graph.h start--------------------------------------------

#include <bits/stdc++.h>
using namespace std;

template <typename Weight>
struct Vertex;
template <typename Weight>
struct Edge;

template <typename Weight>
struct Vertex
{
  int id;
  long long l;
  vector<int> ids_dst;
  vector<Edge<Weight>> edges;

  Vertex(const int id = 0) : id(id){};
  int &operator[](int n) { return ids_dst[n]; }
  const int &operator[](int n) const { return ids_dst[n]; }

  size_t size() const { return edges.size(); }
  void add_edge(const Edge<Weight> &);
};

template <typename Weight>
struct Edge
{
  int id_src, id_dst;
  Weight weight;

  Edge(const int id_src, const int id_dst) : id_src(id_src), id_dst(id_dst){};
  Edge(const int id_src, const int id_dst, const Weight weight) : id_src(id_src), id_dst(id_dst), weight(weight){};
};
template <typename Weight>
ostream &operator<<(ostream &os, const Edge<Weight> &e) { return os << "Edge(" << e.id_src << "->" << e.id_dst << "," << e.weight << ")"; }

template <typename Weight = long long>
struct Graph
{
  vector<Vertex<Weight>> vertices;
  vector<Edge<Weight>> edges;

  Graph(const int nvertices = 0);
  Vertex<Weight> &operator[](int n) { return vertices[n]; }
  const Vertex<Weight> &operator[](int n) const { return vertices[n]; }

  size_t size() const { return vertices.size(); }
  void add_edge(const Edge<Weight> &);
  void add_edge(const int id_src, const int id_dst) { add_edge({id_src, id_dst}); };
  void add_edge(const int id_src, const int id_dst, const Weight w) { add_edge({id_src, id_dst, w}); };
};
template <typename Weight>
ostream &operator<<(ostream &os, const Graph<Weight> &g)
{
  cout << "Graph(" << g.size() << ")"
       << "[" << endl;
  for (auto &e : g.edges)
    os << " " << e << "," << endl;
  cout << "]";
  return os;
}

//----------------------------------------------------------

template <typename Weight>
void Vertex<Weight>::add_edge(const Edge<Weight> &e)
{
  edges.push_back(e);
  ids_dst.push_back(e.id_dst);
}

template <typename Weight>
bool operator<(const Edge<Weight> &e1, const Edge<Weight> &e2)
{
  return e1.weight != e2.weight ? e1.weight > e2.weight : // !!INVERSE!!
             e1.id_src != e2.id_src ? e1.id_src < e2.id_src : e1.id_dst < e2.id_dst;
}

template <typename Weight>
Graph<Weight>::Graph(const int nvertices)
{
  for (int id = 0; id < nvertices; id++)
    vertices.emplace_back(id);
}
template <typename Weight>
void Graph<Weight>::add_edge(const Edge<Weight> &e)
{
  edges.push_back(e);
  vertices[e.id_src].add_edge(e);
}

template <typename Weight>
Graph<Weight> make_tree(Graph<Weight> &g)
{
  int nvertices = g.size();
  Graph<Weight> g_tree(nvertices);
  queue<int> q;
  vector<bool> is_used(nvertices, false);

  int v_start = 0;
  q.push(v_start);
  is_used[v_start] = true;
  while (!q.empty())
  {
    int v = q.front();
    q.pop();
    for (int c : g[v].ids_dst)
    {
      if (is_used[c])
        continue;
      g_tree.add_edge(v, c);
      g_tree.add_edge(c, v);
      q.push(c);
      is_used[c] = true;
    }
  }

  return g_tree;
}

// Graph.h end----------------------------------------------

// Rerooting.h start--------------------------------------------

#include <vector>
#include <set>

template <typename Weight>
struct Rerooting
{
  const vector<Vertex<Weight>> &vertices;

  // edit from here ----------------------------------------------------
  struct DP
  {
    long long b;
    ll sum_l;
    DP() : b(0), sum_l(0){};
    DP &operator+=(const DP &rhs)
    {
      sum_l += rhs.sum_l;
      b += rhs.b;
      return *this;
    }
    // DP &operator-=(const DP &rhs)
    // {
    //   sum_l -= rhs.sum_l;
    //   b -= rhs.b;
    //   return *this;
    // }
    inline DP operator+(const DP &rhs) const
    {
      return DP(*this) += rhs;
    }
    // inline DP operator-(const DP &rhs) const
    // {
    //   return DP(*this) -= rhs;
    // }
  };
  DP add_root(DP dp, const int v)
  {
    dp.b += dp.sum_l;
    dp.sum_l += vertices[v].l;
    return dp;
  }

  // edit until here ----------------------------------------------------

  vector<vector<DP>> dp;
  vector<DP> ans;
  Rerooting(const Graph<Weight> &g) : vertices(g.vertices), dp(g.size()), ans(g.size()){};

  void init()
  {
    const int root_init = 0;
    dfs(root_init);
    bfs(root_init);
  }
  DP dfs(int v, int parent = -1)
  {
    DP dp_sum;
    int n = vertices[v].size();
    dp[v] = vector<DP>(n);
    for (int i = 0; i < n; i++)
    {
      const int child = vertices[v][i];
      if (child == parent)
        continue;
      dp_sum += dp[v][i] = dfs(child, v);
    }
    return add_root(dp_sum, v);
  }
  void bfs(int v, int parent = -1, const DP &dp_parent = DP())
  {
    const int n = vertices[v].size();
    for (int i = 0; i < n; i++)
      if (vertices[v][i] == parent)
        dp[v][i] = dp_parent;

    vector<DP> dp_sum_left(n + 1);
    for (int i = 0; i < n; i++)
      dp_sum_left[i + 1] = dp_sum_left[i] + dp[v][i];
    vector<DP> dp_sum_right(n + 1);
    for (int i = n - 1; i >= 0; i--)
      dp_sum_right[i] = dp[v][i] + dp_sum_right[i + 1];

    ans[v] = add_root(dp_sum_left[n], v);

    for (int i = 0; i < n; i++)
    {
      int child = vertices[v][i];
      if (child == parent)
        continue;
      const DP dp_sum_without_i = dp_sum_left[i] + dp_sum_right[i + 1];
      bfs(child, v, add_root(dp_sum_without_i, v));
    }
  }
};

// Rerooting.h end----------------------------------------------

void solve()
{
  int N;
  cin >> N;
  Graph g(N);
  rep(i, N)
  {
    int l;
    cin >> l;
    g[i].l = l;
  }
  rep(i, N - 1)
  {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    g.add_edge(a, b);
    g.add_edge(b, a);
  }

  Rerooting rt(g);
  rt.init();
  auto ans = rt.ans;
  rep(i, N)
  {
    cout << ans[i].b << endl;
  }
}

int main()
{
  cout << fixed << setprecision(15);

  solve();
  return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 51440
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

//////////////////////////////   Begin Macros

#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define in(x, a, b) (a <= x and x < b)
#define rep(i, N) for (int i = 0; i < (int)(N); i++)
#define reprev(i, N) for (int i = (int)(N)-1; i >= 0; i--)
#define rep1(i, N) for (int i = 1; i <= (int)(N); i++)
#define rep1rev(i, N) for (int i = (int)(N); i >= 0; i--)
#define forbe(i, b, e) for (int i = (b); i < (e); i++)
#define forberev(i, b, e) for (int i = (e)-1; i >= (b); i--)
#define forfl(i, f, l) for (int i = (f); i <= (l); i++)
#define forflrev(i, f, l) for (int i = (l); i >= (f); i--)
using ll = long long;
using pii = pair<int, int>;
using pil = pair<int, ll>;
using pli = pair<ll, int>;
using pll = pair<ll, ll>;

template <typename T>
bool chmax(T &m, const T q)
{
  if (m < q)
  {
    m = q;
    return true;
  }
  else
    return false;
}
template <typename T>
bool chmin(T &m, const T q)
{
  if (m > q)
  {
    m = q;
    return true;
  }
  else
    return false;
}
template <typename T1, typename T2>
pair<T1, T2> operator+(const pair<T1, T2> &l, const pair<T1, T2> &r) { return {l.first + r.first, l.second + r.second}; }
template <typename T1, typename T2>
pair<T1, T2> operator-(const pair<T1, T2> &l, const pair<T1, T2> &r) { return {l.first - r.first, l.second - r.second}; }
template <typename T>
pair<T, T> operator*(const pair<T, T> &l, const T &r) { return {l.first * r, l.second * r}; }
template <typename T>
pair<T, T> operator/(const pair<T, T> &l, const T &r) { return {l.first / r, l.second / r}; }
template <typename T>
istream &operator>>(istream &is, vector<T> &vec)
{
  for (auto &v : vec)
    is >> v;
  return is;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &vec)
{
  os << "[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const deque<T> &vec)
{
  os << "deq[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const set<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_set<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const multiset<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_multiset<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &pa)
{
  is >> pa.first >> pa.second;
  return is;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &pa)
{
  os << "(" << pa.first << "," << pa.second << ")";
  return os;
}
template <typename... Ts>
istream &operator>>(istream &is, tuple<Ts...> &theTuple)
{
  apply([&is](Ts &... tupleArgs) { ((is >> tupleArgs), ...); }, theTuple);
  return is;
}
template <typename... Ts>
ostream &operator<<(ostream &os, const tuple<Ts...> &theTuple)
{
  apply([&os](const Ts &... tupleArgs) {
    os << '(';
    size_t n(0);
    ((os << tupleArgs << (++n < sizeof...(Ts) ? "," : "")), ...);
    os << ')';
  },
        theTuple);
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const map<TK, TV> &mp)
{
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp)
{
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}

template <typename T>
void reset(vector<T> &v, const T reset_to)
{
  for (auto &x : v)
    x = reset_to;
}
inline int popcount(const unsigned int x) { return __builtin_popcount(x); }
#define dbg(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;

ll nC2(ll n)
{
  return n * (n - 1) / 2;
}

const int intinf = numeric_limits<int>::max();
const ll llinf = numeric_limits<ll>::max();
const pii udlr[4] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

//////////////////////////////   End Macros

// Graph.h start--------------------------------------------

#include <bits/stdc++.h>
using namespace std;

template <typename Weight>
struct Vertex;
template <typename Weight>
struct Edge;

template <typename Weight>
struct Vertex
{
  int id;
  long long l;
  vector<int> ids_dst;
  vector<Edge<Weight>> edges;

  Vertex(const int id = 0) : id(id){};
  int &operator[](int n) { return ids_dst[n]; }
  const int &operator[](int n) const { return ids_dst[n]; }

  size_t size() const { return edges.size(); }
  void add_edge(const Edge<Weight> &);
};

template <typename Weight>
struct Edge
{
  int id_src, id_dst;
  Weight weight;

  Edge(const int id_src, const int id_dst) : id_src(id_src), id_dst(id_dst){};
  Edge(const int id_src, const int id_dst, const Weight weight) : id_src(id_src), id_dst(id_dst), weight(weight){};
};
template <typename Weight>
ostream &operator<<(ostream &os, const Edge<Weight> &e) { return os << "Edge(" << e.id_src << "->" << e.id_dst << "," << e.weight << ")"; }

template <typename Weight = long long>
struct Graph
{
  vector<Vertex<Weight>> vertices;
  vector<Edge<Weight>> edges;

  Graph(const int nvertices = 0);
  Vertex<Weight> &operator[](int n) { return vertices[n]; }
  const Vertex<Weight> &operator[](int n) const { return vertices[n]; }

  size_t size() const { return vertices.size(); }
  void add_edge(const Edge<Weight> &);
  void add_edge(const int id_src, const int id_dst) { add_edge({id_src, id_dst}); };
  void add_edge(const int id_src, const int id_dst, const Weight w) { add_edge({id_src, id_dst, w}); };
};
template <typename Weight>
ostream &operator<<(ostream &os, const Graph<Weight> &g)
{
  cout << "Graph(" << g.size() << ")"
       << "[" << endl;
  for (auto &e : g.edges)
    os << " " << e << "," << endl;
  cout << "]";
  return os;
}

//----------------------------------------------------------

template <typename Weight>
void Vertex<Weight>::add_edge(const Edge<Weight> &e)
{
  edges.push_back(e);
  ids_dst.push_back(e.id_dst);
}

template <typename Weight>
bool operator<(const Edge<Weight> &e1, const Edge<Weight> &e2)
{
  return e1.weight != e2.weight ? e1.weight > e2.weight : // !!INVERSE!!
             e1.id_src != e2.id_src ? e1.id_src < e2.id_src : e1.id_dst < e2.id_dst;
}

template <typename Weight>
Graph<Weight>::Graph(const int nvertices)
{
  for (int id = 0; id < nvertices; id++)
    vertices.emplace_back(id);
}
template <typename Weight>
void Graph<Weight>::add_edge(const Edge<Weight> &e)
{
  edges.push_back(e);
  vertices[e.id_src].add_edge(e);
}

template <typename Weight>
Graph<Weight> make_tree(Graph<Weight> &g)
{
  int nvertices = g.size();
  Graph<Weight> g_tree(nvertices);
  queue<int> q;
  vector<bool> is_used(nvertices, false);

  int v_start = 0;
  q.push(v_start);
  is_used[v_start] = true;
  while (!q.empty())
  {
    int v = q.front();
    q.pop();
    for (int c : g[v].ids_dst)
    {
      if (is_used[c])
        continue;
      g_tree.add_edge(v, c);
      g_tree.add_edge(c, v);
      q.push(c);
      is_used[c] = true;
    }
  }

  return g_tree;
}

// Graph.h end----------------------------------------------

// Rerooting.h start--------------------------------------------

#include <vector>
#include <set>

template <typename Weight>
struct Rerooting
{
  const vector<Vertex<Weight>> &vertices;

  // edit from here ----------------------------------------------------
  struct DP
  {
    long long b;
    ll sum_l;
    DP() : b(0), sum_l(0){};
    DP &operator+=(const DP &rhs)
    {
      sum_l += rhs.sum_l;
      b += rhs.b + rhs.sum_l;
      return *this;
    }
    DP &operator-=(const DP &rhs)
    {
      sum_l -= rhs.sum_l;
      b -= rhs.b + rhs.sum_l;
      return *this;
    }
    inline DP operator+(const DP &rhs) const
    {
      return DP(*this) += rhs;
    }
    inline DP operator-(const DP &rhs) const
    {
      return DP(*this) -= rhs;
    }
  };
  DP add_root(DP dp, const int v)
  {
    dp.sum_l += vertices[v].l;
    return dp;
  }

  // edit until here ----------------------------------------------------

  vector<vector<DP>> dp;
  vector<DP> ans;
  Rerooting(const Graph<Weight> &g) : vertices(g.vertices), dp(g.size()), ans(g.size()){};

  void init()
  {
    const int root_init = 0;
    dfs(root_init);
    bfs(root_init);
  }
  DP dfs(int v, int parent = -1)
  {
    DP dp_sum;
    int n = vertices[v].size();
    dp[v] = vector<DP>(n);
    for (int i = 0; i < n; i++)
    {
      const int child = vertices[v][i];
      if (child == parent)
        continue;
      dp_sum += dp[v][i] = dfs(child, v);
    }
    return add_root(dp_sum, v);
  }

  void bfs(int v, int parent = -1, const DP &dp_parent = DP())
  {
    const int n = vertices[v].size();
    for (int i = 0; i < n; i++)
      if (vertices[v][i] == parent)
        dp[v][i] = dp_parent;

    DP dp_sum;
    for (int i = 0; i < n; i++)
      dp_sum += dp[v][i];

    ans[v] = add_root(dp_sum, v);
    for (int i = 0; i < n; i++)
    {
      int child = vertices[v][i];
      if (child == parent)
        continue;
      const DP dp_sum_without_i = dp_sum - dp[v][i];
      bfs(child, v, add_root(dp_sum_without_i, v));
    }
  }
};

// Rerooting.h end----------------------------------------------

void solve()
{
  int N;
  cin >> N;
  Graph g(N);
  rep(i, N)
  {
    int l;
    cin >> l;
    g[i].l = l;
  }
  rep(i, N - 1)
  {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    g.add_edge(a, b);
    g.add_edge(b, a);
  }

  Rerooting rt(g);
  rt.init();
  auto ans = rt.ans;
  rep(i, N)
  {
    cout << ans[i].b << endl;
  }
}

int main()
{
  cout << fixed << setprecision(15);

  solve();
  return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 40896
final_rank: 19

code_snippet: // clang-format off
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}
// clang-format on

const int N = 100010;
ll L[N];
vector<int> G[N];

ll sL = 0;

ll s[N], d[N];
void calc(int v, int p) {
    s[v] = L[v];
    for (int e : G[v])
        if (e != p) {
            d[e] = d[v] + 1;
            calc(e, v);
            s[v] += s[e];
        }
}

ll ans[N];
void dfs(int v, int p, ll now) {
    ans[v] = now;
    for (int e : G[v])
        if (e != p) {
            ll t = now - s[e] + (sL - s[e]);
            dfs(e, v, t);
        }
}

int main() {
    int n;
    cin >> n;
    rep(i, n) {
        cin >> L[i];
        sL += L[i];
    }
    rep(i, n - 1) {
        int a, b;
        cin >> a >> b;
        --a;
        --b;
        G[a].pb(b);
        G[b].pb(a);
    }

    calc(0, -1);

    ll v0 = 0;
    rep(i, n) v0 += L[i] * d[i];

    dfs(0, -1, v0);

    rep(i, n) cout << ans[i] << "\n";
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 16988
final_rank: 9