Problem:
G: Restricted DFS
問題
N
頂点
N-1
辺からなる、自己ループや多重辺が存在しない無向木
G
がある。頂点はそれぞれ
1
から
N
まで番号付けされており、辺もそれぞれ
1
から
N-1
まで番号付けされており、
i
番目の辺は
u_i
と
v_i
を結んでいる。また、
i
番目の頂点には非負整数
A_i
がそれぞれ割り当てられている。
この木に対して、根
r
から以下の擬似コードにしたがって DFS (深さ優先探索) を行うことを考える。
// [input]
// G: dfs の対象となるグラフ
// A: それぞれの頂点に割り当てられた非負整数
// v: dfs を開始する頂点
// step: ステップ数を記録する整数

// [output]
// 以下のうちどちらかの二値
// - SUCCESS: dfs が途中で終了することなく、頂点 v まで戻ってくる
// - FAILURE: dfs が途中で終了する

function dfs(G, A, v, step)
    if (A[v] が 0 である) then
        return FAILURE

    A[v] ← A[v] - 1
    step ← step + 1
    v の子を頂点番号が小さい順にソート

    // c は頂点番号が小さい順に見られる
    for each (v の子 c) do
        if (dfs(G, A, c, step) が FAILURE である) then
            return FAILURE

        if (A[v] が 0 である) then
            return FAILURE

        A[v] ← A[v] - 1
        step ← step + 1

    return SUCCESS
つまり、与えられた
G
と
A
に対して、根
r
について
dfs(G, A, r, 0)
を実行することを考える。
それぞれの頂点を根としたときの、この DFS のステップ数を求めよ。
入力形式
N
A_1
...
A_N
u_1
v_1
...
u_{N-1}
v_{N-1}
1
行目では、与えられるグラフの頂点数
N
が与えられる。
2
行目は
N
個の整数からなる。
i
個目の整数
A_i
は、
i
番目の頂点に書かれている値を表す。
3
行目から
N+1
行目までは、与えられるグラフの辺の情報が与えられる。
u_i, v_i
は、頂点
u_i
と頂点
v_i
を結ぶ無向辺がグラフ中に存在することを表す。
制約
1 \leq N \leq 3 \times 10^5
0 \leq A_i \leq 10^9
1 \leq u_i < v_i \leq N
与えられるグラフは木であることが保証される
入力は全て整数で与えられる
出力形式
N
行出力せよ。
i
行目には、頂点
i
を根としたときのステップ数を出力せよ。
入力例1
3
1 2 3
1 2
1 3
出力例1
2
3
3
1
番目の頂点を根としたとき
頂点
1
(
A_1
:
1
→
0
) → 頂点
2
(
A_2
:
2
→
1
) → 頂点
1
(
A_1
が
0
であるため、頂点
1
に訪れることなく終了する)
2
番目の頂点を根としたとき
頂点
2
(
A_2
:
2
→
1
) → 頂点
1
(
A_1
:
1
→
0
) → 頂点
3
(
A_3
:
3
→
2
) → 頂点
1
(
A_1
が
0
であるため、頂点
1
に訪れることなく終了する)
3
番目の頂点を根としたとき
頂点
3
(
A_3
:
3
→
2
) → 頂点
1
(
A_1
:
1
→
0
) → 頂点
2
(
A_2
:
2
→
1
) → 頂点
1
(
A_1
が
0
であるため、頂点
1
に訪れることなく終了する)
よって、答えはそれぞれ
2, 3, 3
となる。はじめに根から出発するときも
A_i
の値を減らすことに注意せよ。
入力例2
3
1 2 3
1 2
2 3
出力例2
4
4
5

Submitted solutions:

code_snippet: #include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <unordered_map>

using namespace std;

#define int long long

vector<vector<int>> graph;
vector<bool> res;
vector<int> cnt;
vector<int> vec2;
vector<int> p0;
vector<unordered_map<int, int>> um;
vector<vector<int>> rcnt;
vector<vector<bool>> rres;

pair<int, bool> dfs2(int v, int par) {
	if (um[v][par] != 0) {
		int id = um[v][par] - 1;
		return { rcnt[v][id], rres[v][id] };
	}
	if (vec2[v] == 0) return { 0, false };
	int a1 = vec2[v];
	a1--;
	int ans = 1;
	bool cres = true;
	for (auto c : graph[v]) {
		if (c == par) continue;
		auto a = dfs2(c, v);
		ans += a.first;
		if (!a.second || a1 == 0) {
			cres = false;
			break;
		}
		a1--;
		ans++;
	}
	return { ans, cres };
}

void calcVertex(int p, vector<int>& vec) {
	int n = cnt.size();
	cnt.assign(n, 0);
	res.assign(n, false);
	vec2 = vec;
	vector<pair<int, bool>> v;
	for (auto c : graph[p]) {
		v.push_back(dfs2(c, p));
	}
	vector<int> ifalse;
	for (int i = 0; i < v.size(); i++) {
		if (!v[i].second) ifalse.push_back(i);
	}
	vector<int> pref(1, 0);
	for (auto c : v) pref.push_back(pref.back() + c.first);
	for (int i = 0; i < v.size(); i++) {
		int par = graph[p][i];
		int br = -1;
		if (ifalse.size() > 0) br = ifalse[0];
		if (br == i) {
			br = -1;
			if (ifalse.size() > 1) br = ifalse[1];
		}
		bool cres = false;
		if (br == -1) cres = true;
		if (br == -1) br = pref.size() - 2;
		int limit = vec2[p] - 1;
		if (i - 1 <= limit) limit++;
		if (limit <= br) {
			br = min(br, limit);
			cres = false;
		}
		int ans = pref[br + 1];
		ans += br + 1;
		if (i <= br) {
			ans -= v[i].first;
			ans--;
		}
		if (cres) ans++;
		if (um[p][par] == 0) {
			um[p][par] = rcnt[p].size() + 1;
			rcnt[p].push_back(ans);
			rres[p].push_back(cres);
		}
	}
}

signed main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t0 = clock();
	int n; cin >> n;
	vector<int> vec(n);
	p0.resize(n);
	for (int i = 0; i < n; i++) cin >> vec[i];
	graph.resize(n);
	for (int i = 0; i < n - 1; i++) {
		int a, b; cin >> a >> b; a--; b--;
		graph[a].push_back(b);
		graph[b].push_back(a);
	}
	for (int i = 0; i < n; i++) {
		sort(graph[i].begin(), graph[i].end());
	}
	vector<int> calcfrom;
	vector<pair<int, int>> vp;
	for (int i = 0; i < n; i++) vp.push_back({ graph[i].size(), i });
	sort(vp.rbegin(), vp.rend());
	for (int i = 0; i < min(n, 10000ll); i++) {
		calcfrom.push_back(vp[i].second);
	}
	rres.resize(n);
	um.resize(n);
	rcnt.resize(n);
	for (auto p : calcfrom) {
		calcVertex(p, vec);
	}
	vec2 = vec;
	for (int i = 0; i < n; i++) {
		int answ = dfs2(i, i).first;
		cout << answ << endl;
	}
}
accuracy: 1
time_ms: 1910
memory_kb: 117276
final_rank: 12

code_snippet: #include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <unordered_map>
#include <fstream>
using namespace std;

//#define int long long

vector<vector<int>> graph;
vector<bool> res;
vector<int> cnt;
vector<int> vec2;
vector<int> p0;
vector<unordered_map<int, int>> um;
vector<vector<int>> rcnt;
vector<vector<bool>> rres;

pair<int, bool> dfs2(int v, int par) {
	if (um[v][par] != 0) {
		int id = um[v][par] - 1;
		return { rcnt[v][id], rres[v][id] };
	}
	if (vec2[v] == 0) return { 0, false };
	int a1 = vec2[v];
	a1--;
	int ans = 1;
	bool cres = true;
	for (auto c : graph[v]) {
		if (c == par) continue;
		auto a = dfs2(c, v);
		ans += a.first;
		if (!a.second || a1 == 0) {
			cres = false;
			break;
		}
		a1--;
		ans++;
	}
	//um[v][par] = rcnt[v].size();
	//rcnt[v].push_back(ans);
	//rres[v].push_back(cres);
	return { ans, cres };
}

void calcVertex(int p, vector<int>& vec) {
	int n = cnt.size();
	cnt.assign(n, 0);
	res.assign(n, false);
	vec2 = vec;
	vector<pair<int, bool>> v;
	for (auto c : graph[p]) {
		v.push_back(dfs2(c, p));
	}
	vector<int> ifalse;
	for (int i = 0; i < v.size(); i++) {
		if (!v[i].second) ifalse.push_back(i);
	}
	vector<int> pref(1, 0);
	for (auto c : v) pref.push_back(pref.back() + c.first);
	for (int i = 0; i < v.size(); i++) {
		int par = graph[p][i];
		int br = -1;
		if (ifalse.size() > 0) br = ifalse[0];
		if (br == i) {
			br = -1;
			if (ifalse.size() > 1) br = ifalse[1];
		}
		bool cres = false;
		if (br == -1) cres = true;
		if (br == -1) br = pref.size() - 2;
		int limit = vec2[p] - 1;
		if (i - 1 <= limit) limit++;
		if (limit <= br) {
			br = min(br, limit);
			cres = false;
		}
		int ans = pref[br + 1];
		ans += br + 1;
		if (i <= br) {
			ans -= v[i].first;
			ans--;
		}
		if (cres) ans++;
		if (um[p][par] == 0) {
			um[p][par] = rcnt[p].size() + 1;
			rcnt[p].push_back(ans);
			rres[p].push_back(cres);
		}
	}
}

signed main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	ifstream fin("in60.txt");
	int t0 = clock();
	int n; cin >> n;
	vector<int> vec(n);
	p0.resize(n);
	for (int i = 0; i < n; i++) cin >> vec[i];
	graph.resize(n);
	for (int i = 0; i < n - 1; i++) {
		int a, b; cin >> a >> b; a--; b--;
		graph[a].push_back(b);
		graph[b].push_back(a);
	}
	for (int i = 0; i < n; i++) {
		sort(graph[i].begin(), graph[i].end());
	}
	vector<int> calcfrom;
	vector<pair<int, int>> vp;
	for (int i = 0; i < n; i++) vp.push_back({ graph[i].size(), i });
	sort(vp.rbegin(), vp.rend());
	for (int i = 0; i < min(n, 8000); i++) {
		calcfrom.push_back(vp[i].second);
	}
	rres.resize(n);
	um.resize(n);
	rcnt.resize(n);
	for (auto p : calcfrom) {
		calcVertex(p, vec);
	}
	//cout << (clock() - t0) / (double)CLOCKS_PER_SEC << endl;
	vec2 = vec;
	for (int i = 0; i < n; i++) {
		int answ = dfs2(i, i).first;
		cout << answ << endl;
	}
	//cout << (clock() - t0) / (double)CLOCKS_PER_SEC << endl;
}
accuracy: 1
time_ms: 1570
memory_kb: 107208
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <unordered_map>
#include <fstream>
using namespace std;

#define int long long

vector<vector<int>> graph;
vector<bool> res;
vector<int> cnt;
vector<int> vec2;
vector<int> p0;
vector<unordered_map<int, int>> um;
vector<vector<int>> rcnt;
vector<vector<bool>> rres;

pair<int, bool> dfs2(int v, int par) {
	if (um[v][par] != 0) {
		int id = um[v][par] - 1;
		return { rcnt[v][id], rres[v][id] };
	}
	if (vec2[v] == 0) return { 0, false };
	int a1 = vec2[v];
	a1--;
	int ans = 1;
	bool cres = true;
	for (auto c : graph[v]) {
		if (c == par) continue;
		auto a = dfs2(c, v);
		ans += a.first;
		if (!a.second || a1 == 0) {
			cres = false;
			break;
		}
		a1--;
		ans++;
	}
	//um[v][par] = rcnt[v].size();
	//rcnt[v].push_back(ans);
	//rres[v].push_back(cres);
	return { ans, cres };
}

void calcVertex(int p, vector<int>& vec) {
	int n = cnt.size();
	cnt.assign(n, 0);
	res.assign(n, false);
	vec2 = vec;
	vector<pair<int, bool>> v;
	for (auto c : graph[p]) {
		v.push_back(dfs2(c, p));
	}
	vector<int> ifalse;
	for (int i = 0; i < v.size(); i++) {
		if (!v[i].second) ifalse.push_back(i);
	}
	vector<int> pref(1, 0);
	for (auto c : v) pref.push_back(pref.back() + c.first);
	for (int i = 0; i < v.size(); i++) {
		int par = graph[p][i];
		int br = -1;
		if (ifalse.size() > 0) br = ifalse[0];
		if (br == i) {
			br = -1;
			if (ifalse.size() > 1) br = ifalse[1];
		}
		bool cres = false;
		if (br == -1) cres = true;
		if (br == -1) br = pref.size() - 2;
		int limit = vec2[p] - 1;
		if (i - 1 <= limit) limit++;
		if (limit <= br) {
			br = min(br, limit);
			cres = false;
		}
		int ans = pref[br + 1];
		ans += br + 1;
		if (i <= br) {
			ans -= v[i].first;
			ans--;
		}
		if (cres) ans++;
		if (um[p][par] == 0) {
			um[p][par] = rcnt[p].size() + 1;
			rcnt[p].push_back(ans);
			rres[p].push_back(cres);
		}
	}
}

signed main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	ifstream fin("in60.txt");
	int t0 = clock();
	int n; cin >> n;
	vector<int> vec(n);
	p0.resize(n);
	for (int i = 0; i < n; i++) cin >> vec[i];
	graph.resize(n);
	for (int i = 0; i < n - 1; i++) {
		int a, b; cin >> a >> b; a--; b--;
		graph[a].push_back(b);
		graph[b].push_back(a);
	}
	for (int i = 0; i < n; i++) {
		sort(graph[i].begin(), graph[i].end());
	}
	vector<int> calcfrom;
	vector<pair<int, int>> vp;
	for (int i = 0; i < n; i++) vp.push_back({ graph[i].size(), i });
	sort(vp.rbegin(), vp.rend());
	for (int i = 0; i < min(n, 10000ll); i++) {
		calcfrom.push_back(vp[i].second);
	}
	rres.resize(n);
	um.resize(n);
	rcnt.resize(n);
	for (auto p : calcfrom) {
		calcVertex(p, vec);
	}
	//cout << (clock() - t0) / (double)CLOCKS_PER_SEC << endl;
	vec2 = vec;
	for (int i = 0; i < n; i++) {
		int answ = dfs2(i, i).first;
		cout << answ << endl;
	}
	//cout << (clock() - t0) / (double)CLOCKS_PER_SEC << endl;
}
accuracy: 1
time_ms: 1900
memory_kb: 117828
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,n)for (int i = 0; i < int(n); ++i)

template<class S, class E>
struct Rerooting {
  const vector<vector<E>>& g;
  const int n;
  const int root;
  vector<vector<S>> dp, sl, sr;

  Rerooting(const vector<vector<E>>& g, int root=0): g(g), n(g.size()), root(root), dp(n), sl(n), sr(n) {
    dfs1(root);
    dfs2(root);
  }

  S dfs1(int u, int p=-1) {
    const int sz = g[u].size();
    dp[u].resize(sz);
    sl[u].resize(sz + 1);
    sr[u].resize(sz + 1);

    S res;
    for(int i = 0; i < sz; i++) {
      const E& e = g[u][i];
      int v = dest(e);
      if (v == p) continue;
      dp[u][i] = dfs1(v, u).apply(e);
      res = res.merge(dp[u][i]);
    }
    return res;
  }

  void dfs2(int u, int p=-1) {
    const int sz = g[u].size();

    {
      S s;
      for(int i = 0; i < sz; i++) {
        s = s.merge(dp[u][i]);
        sl[u][i + 1] = s;
      }
    }
    {
      S s;
      for(int i = sz - 1; i >= 0; i--) {
        s = dp[u][i].merge(s);
        sr[u][i] = s;
      }
    }

    for(int i = 0; i < sz; i++) {
      int v = dest(g[u][i]);
      if (v == p) continue;
      const int sz_v = g[v].size();
      for(int j = 0; j < sz_v; j++) {
        const E& e = g[v][j];
        int w = dest(e);
        if (w != u) continue;
        dp[v][j] = sl[u][i].merge(sr[u][i + 1]).apply(e);
        break;
      }
      dfs2(v, u);
    }
  }

  S get_acc(int v) { return sr[v][0]; }
  S get_res(int v, E e) { return sr[v][0].apply(e); }

  private:
  int dest(const E& e) {
    if constexpr (is_same<E, int>::value) return e;
    else return e.to;
  };
};


int A[300000];
struct E { int from, to, idx; };
struct S {
  struct T {
    int step = 0;
    bool cont = true;
    int cnt = 0;
    T merge(const T& rhs) const {
      if (cont) {
        return { step + rhs.step,
                 rhs.cont,
                 cnt + rhs.cnt };
      } else {
        return *this;
      }
    }
  };
  T d1, d2;
  S apply(E e) const {
    T d;
    if (d2.cnt <= A[e.to]) d = d2;
    else d = d1;
    d.step++;
    if (d.cont) {
      if (d.cnt == A[e.to]) d.cont = false;
      else d.step++;
    }
    d.cnt = 1;
    if (e.idx < A[e.from]) {
      return {d, d};
    } else if (e.idx == A[e.from]) {
      return {{0, false, 0}, d};
    } else {
      return {{0, false, 0}, {0, false, 0}};
    }
  }
  S merge(const S& rhs) const {
    return { d1.merge(rhs.d1), d2.merge(rhs.d2) };
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int n;
  cin >> n;
  rep(i, n) cin >> A[i];
  vector<vector<E>> g(n);
  rep(i, n - 1) {
    int u, v;
    cin >> u >> v;
    u--, v--;
    g[u].push_back({u, v});
    g[v].push_back({v, u});
  }
  rep(i, n) {
    sort(g[i].begin(), g[i].end(), [&](const E& e1, const E& e2) {
      return e1.to < e2.to;
    });
    int idx = 0;
    for(auto& e: g[i]) e.idx = idx++;
  }
  Rerooting<S, E> dp(g);
  rep(i, n) {
    S::T res = dp.get_acc(i).d1;
    int ans = res.step;
    if (res.cont && res.cnt < A[i]) ans++;
    cout << ans << '\n';
  }
}
accuracy: 1
time_ms: 380
memory_kb: 116020
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define REP(i, m, n) for (int i = m; i < (ll)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define all(v) v.begin(), v.end()


#include <algorithm>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <vector>

namespace atcoder {

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
  public:
    segtree() : segtree(0) {}
    segtree(int n) : segtree(std::vector<S>(n, e())) {}
    segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = internal::ceil_pow2(_n);
        size = 1 << log;
        d = std::vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        return d[p + size];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        l += size;
        r += size;

        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    template <bool (*f)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return f(x); });
    }
    template <class F> int max_right(int l, F f) {
        assert(0 <= l && l <= _n);
        assert(f(e()));
        if (l == _n) return _n;
        l += size;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*f)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return f(x); });
    }
    template <class F> int min_left(int r, F f) {
        assert(0 <= r && r <= _n);
        assert(f(e()));
        if (r == 0) return 0;
        r += size;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
                while (r < size) {
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

}  // namespace atcoder

using namespace atcoder;

struct T {
  ll cnt;
  bool suc;
};
struct S {
  T val;
  int len;
};

S op(S a, S b) {
  if (not a.val.suc) return a;
  a.val.cnt += b.val.cnt;
  a.val.suc &= b.val.suc;
  a.len += b.len;
  return a;
}
S e() { return {{0, true}, 0}; }

int n;
int a[300010];
vector<int> G[300010];
vector<vector<T>> dp;

const int root = 0;

T dfs1(int p, int v) {
  int ch = G[v].size();
  if (v != root) ch--;
  segtree<S, op, e> seg(ch);
  int j = 0;
  for (int i = 0; i < G[v].size(); ++i) {
    if (G[v][i] == p) continue;
    dp[v][i] = dfs1(v, G[v][i]);
    seg.set(j++, {dp[v][i], 1});
  }
  T res;
  S s;
  if (a[v] > ch) {
    s = seg.all_prod();
    res.cnt = s.val.cnt + s.len;
    res.suc = s.val.suc;
    if (res.suc) res.cnt++;
  } else {
    s = seg.prod(0, a[v]);
    res.cnt = s.val.cnt + s.len;
    res.suc = false;
  }
  return res;
}

void dfs2(int p, int v, T from_par) {
  for (int i = 0; i < G[v].size(); ++i) {
    if (G[v][i] == p) {
      dp[v][i] = from_par;
      break;
    }
  }
  int ch = G[v].size() - 1;
  vector<S> tmp(G[v].size());
  rep(i, G[v].size()) tmp[i] = {dp[v][i], 1};
  segtree<S, op, e> seg(tmp);
  for (int i = 0; i < G[v].size(); ++i) {
    if (G[v][i] == p) continue;
    T res;
    S s;
    if (a[v] > ch) {
      s = op(seg.prod(0, i), seg.prod(i + 1, G[v].size()));
      res.cnt = s.val.cnt + s.len;
      res.suc = s.val.suc;
      if (res.suc) res.cnt++;
    } else {
      if (a[v] < i) {
        s = seg.prod(0, a[v]);
      } else {
        s = op(seg.prod(0, i), seg.prod(i + 1, a[v] + 1));
      }
      res.cnt = s.val.cnt + s.len;
      res.suc = false;
    }
    dfs2(v, G[v][i], res);
  }
}

T calc(int v) {
  int ch = G[v].size();
  vector<S> tmp(G[v].size());
  rep(i, G[v].size()) tmp[i] = {dp[v][i], 1};
  segtree<S, op, e> seg(tmp);
  T res;
  S s;
  if (a[v] > ch) {
    s = seg.all_prod();
    res.cnt = s.val.cnt + s.len;
    res.suc = s.val.suc;
    if (res.suc) res.cnt++;
  } else {
    s = seg.prod(0, a[v]);
    res.cnt = s.val.cnt + s.len;
    res.suc = false;
  }
  return res;
}

int main() {
  cin >> n;
  rep(i, n) cin >> a[i];
  rep(i, n - 1) {
    int u, v;
    cin >> u >> v;
    u--, v--;
    G[u].push_back(v);
    G[v].push_back(u);
  }
  rep(i, n) sort(all(G[i]));
  dp.resize(n);
  rep(i, n) dp[i].resize(G[i].size());
  dfs1(-1, root);
  dfs2(-1, 0, {0, true});
  rep(i, n) cout << calc(i).cnt << "\n";
}
accuracy: 1
time_ms: 360
memory_kb: 95820
final_rank: 7

code_snippet: #define MOD_TYPE 2

#pragma region Macros

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



#include <utility>

namespace atcoder {

namespace internal {

// @param m `1 <= m`
// @return x mod m
constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

// Fast modular multiplication by barrett reduction
// Reference: https://en.wikipedia.org/wiki/Barrett_reduction
// NOTE: reconsider after Ice Lake
struct barrett {
    unsigned int _m;
    unsigned long long im;

    // @param m `1 <= m < 2^31`
    barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    // @return m
    unsigned int umod() const { return _m; }

    // @param a `0 <= a < m`
    // @param b `0 <= b < m`
    // @return `a * b % m`
    unsigned int mul(unsigned int a, unsigned int b) const {
        // [1] m = 1
        // a = b = im = 0, so okay

        // [2] m >= 2
        // im = ceil(2^64 / m)
        // -> im * m = 2^64 + r (0 <= r < m)
        // let z = a*b = c*m + d (0 <= c, d < m)
        // a*b * im = (c*m + d) * im = c*(im*m) + d*im = c*2^64 + c*r + d*im
        // c*r + d*im < m * m + m * im < m * m + 2^64 + m <= 2^64 + m * (m + 1) < 2^64 * 2
        // ((ab * im) >> 64) == c or c + 1
        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned int v = (unsigned int)(z - x * _m);
        if (_m <= v) v += _m;
        return v;
    }
};

// @param n `0 <= n`
// @param m `1 <= m`
// @return `(x ** n) % m`
constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

// Reference:
// M. Forisek and J. Jancina,
// Fast Primality Testing for Integers That Fit into a Machine Word
// @param n `0 <= n`
constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    constexpr long long bases[3] = {2, 7, 61};
    for (long long a : bases) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

// @param b `1 <= b`
// @return pair(g, x) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g
constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    // Contracts:
    // [1] s - m0 * a = 0 (mod b)
    // [2] t - m1 * a = 0 (mod b)
    // [3] s * |m1| + t * |m0| <= b
    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b

        // [3]:
        // (s - t * u) * |m1| + t * |m0 - m1 * u|
        // <= s * |m1| - t * u * |m1| + t * (|m0| + |m1| * u)
        // = s * |m1| + t * |m0| <= b

        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    // by [3]: |m0| <= b/g
    // by g != b: |m0| < b/g
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

// Compile time primitive root
// @param m must be prime
// @return primitive root (and minimum in now)
constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

}  // namespace internal

}  // namespace atcoder


#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <numeric>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

struct modint_base {};
struct static_modint_base : modint_base {};

template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;

}  // namespace internal

template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
    using mint = static_modint;

  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    static_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    static_modint(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    static_modint(T v) {
        _v = (unsigned int)(v % umod());
    }
    static_modint(bool v) { _v = ((unsigned int)(v) % umod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = internal::inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = internal::is_prime<m>;
};

template <int id> struct dynamic_modint : internal::modint_base {
    using mint = dynamic_modint;

  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = internal::barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        long long x = (long long)(v % (long long)(mod()));
        if (x < 0) x += mod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        _v = (unsigned int)(v % mod());
    }
    dynamic_modint(bool v) { _v = ((unsigned int)(v) % mod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = internal::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static internal::barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt = 998244353;

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

namespace internal {

template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;

template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;

template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};

template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;

}  // namespace internal

}  // namespace atcoder


#include <algorithm>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <vector>

namespace atcoder {

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
  public:
    segtree() : segtree(0) {}
    segtree(int n) : segtree(std::vector<S>(n, e())) {}
    segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = internal::ceil_pow2(_n);
        size = 1 << log;
        d = std::vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        return d[p + size];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        l += size;
        r += size;

        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    template <bool (*f)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return f(x); });
    }
    template <class F> int max_right(int l, F f) {
        assert(0 <= l && l <= _n);
        assert(f(e()));
        if (l == _n) return _n;
        l += size;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*f)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return f(x); });
    }
    template <class F> int min_left(int r, F f) {
        assert(0 <= r && r <= _n);
        assert(f(e()));
        if (r == 0) return 0;
        r += size;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
                while (r < size) {
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

}  // namespace atcoder


using namespace atcoder;

#if 0
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>
using Int = boost::multiprecision::cpp_int;
using lld = boost::multiprecision::cpp_dec_float_100;
#endif

#if 1
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#endif

using ll = long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pld = pair<ld, ld>;
template <typename Q_type>
using smaller_queue = priority_queue<Q_type, vector<Q_type>, greater<Q_type>>;

#if MOD_TYPE == 1
constexpr ll MOD = ll(1e9 + 7);
#else
#if MOD_TYPE == 2
constexpr ll MOD = 998244353;
#else
constexpr ll MOD = 1000003;
#endif
#endif

using mint = static_modint<MOD>;
constexpr int INF = (int)1e9 + 10;
constexpr ll LINF = (ll)4e18;
constexpr double PI = acos(-1.0);
constexpr double EPS = 1e-11;
constexpr int Dx[] = {0, 0, -1, 1, -1, 1, -1, 1, 0};
constexpr int Dy[] = {1, -1, 0, 0, -1, -1, 1, 1, 0};

#define REP(i, m, n) for (ll i = m; i < (ll)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define REPI(i, m, n) for (int i = m; i < (int)(n); ++i)
#define repi(i, n) REPI(i, 0, n)
#define MP make_pair
#define MT make_tuple
#define YES(n) cout << ((n) ? "YES" : "NO") << "\n"
#define Yes(n) cout << ((n) ? "Yes" : "No") << "\n"
#define possible(n) cout << ((n) ? "possible" : "impossible") << "\n"
#define Possible(n) cout << ((n) ? "Possible" : "Impossible") << "\n"
#define Yay(n) cout << ((n) ? "Yay!" : ":(") << "\n"
#define all(v) v.begin(), v.end()
#define NP(v) next_permutation(all(v))
#define dbg(x) cerr << #x << ":" << x << "\n";
#define UNIQUE(v) v.erase(unique(all(v)), v.end())

struct io_init {
  io_init() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << setprecision(30) << setiosflags(ios::fixed);
  };
} io_init;
template <typename T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
inline ll CEIL(ll a, ll b) { return (a + b - 1) / b; }
template <typename A, size_t N, typename T>
inline void Fill(A (&array)[N], const T &val) {
  fill((T *)array, (T *)(array + N), val);
}
template <typename T>
vector<T> compress(vector<T> &v) {
  vector<T> val = v;
  sort(all(val)), val.erase(unique(all(val)), val.end());
  for (auto &&vi : v) vi = lower_bound(all(val), vi) - val.begin();
  return val;
}
template <typename T, typename U>
constexpr istream &operator>>(istream &is, pair<T, U> &p) noexcept {
  is >> p.first >> p.second;
  return is;
}
template <typename T, typename U>
constexpr ostream &operator<<(ostream &os, pair<T, U> p) noexcept {
  os << p.first << " " << p.second;
  return os;
}
ostream &operator<<(ostream &os, mint m) {
  os << m.val();
  return os;
}

random_device seed_gen;
mt19937_64 engine(seed_gen());

struct BiCoef {
  vector<mint> fact_, inv_, finv_;
  BiCoef(int n) noexcept : fact_(n, 1), inv_(n, 1), finv_(n, 1) {
    fact_.assign(n, 1), inv_.assign(n, 1), finv_.assign(n, 1);
    for (int i = 2; i < n; i++) {
      fact_[i] = fact_[i - 1] * i;
      inv_[i] = -inv_[MOD % i] * (MOD / i);
      finv_[i] = finv_[i - 1] * inv_[i];
    }
  }
  mint C(ll n, ll k) const noexcept {
    if (n < k || n < 0 || k < 0) return 0;
    return fact_[n] * finv_[k] * finv_[n - k];
  }
  mint P(ll n, ll k) const noexcept { return C(n, k) * fact_[k]; }
  mint H(ll n, ll k) const noexcept { return C(n + k - 1, k); }
  mint Ch1(ll n, ll k) const noexcept {
    if (n < 0 || k < 0) return 0;
    mint res = 0;
    for (int i = 0; i < n; i++)
      res += C(n, i) * mint(n - i).pow(k) * (i & 1 ? -1 : 1);
    return res;
  }
  mint fact(ll n) const noexcept {
    if (n < 0) return 0;
    return fact_[n];
  }
  mint inv(ll n) const noexcept {
    if (n < 0) return 0;
    return inv_[n];
  }
  mint finv(ll n) const noexcept {
    if (n < 0) return 0;
    return finv_[n];
  }
};

BiCoef bc(500010);

#pragma endregion

template <typename T>
struct ReRooting {
  using F = function<T(T, int)>;
  using F2 = function<T(T, T)>;
  int V;
  vector<vector<int>> G;
  vector<vector<T>> dp;
  // dp_v = g(merge(f(dp_c1,c1), f(dp_c2,c2), ..., f(dp_ck,ck)), v)
  F f, g;
  F2 merge;
  T mi;  // identity of merge

  ReRooting() {}
  ReRooting(int V, F f, F2 merge, T mi, F g)
      : V(V), f(f), merge(merge), mi(mi), g(g) {
    G.resize(V);
    dp.resize(V);
  }

  void read(int idx = 1) {
    int a, b;
    for (int i = 0; i < V - 1; ++i) {
      cin >> a >> b;
      a -= idx, b -= idx;
      G[a].emplace_back(b);
      G[b].emplace_back(a);
    }
  }

  void add_edge(int a, int b) {
    G[a].emplace_back(b);
    G[b].emplace_back(a);
  }

  T dfs1(int p, int v) {
    T res = mi;
    for (int i = 0; i < G[v].size(); ++i) {
      if (G[v][i] == p) continue;
      dp[v][i] = dfs1(v, G[v][i]);
      res = merge(res, f(dp[v][i], G[v][i]));
    }
    return g(res, v);
  }

  void dfs2(int p, int v, T from_par) {
    for (int i = 0; i < G[v].size(); ++i) {
      if (G[v][i] == p) {
        dp[v][i] = from_par;
        break;
      }
    }
    vector<T> pR(G[v].size() + 1);
    pR[G[v].size()] = mi;
    for (int i = G[v].size(); i > 0; --i)
      pR[i - 1] = merge(pR[i], f(dp[v][i - 1], G[v][i - 1]));
    T pL = mi;
    for (int i = 0; i < G[v].size(); ++i) {
      if (G[v][i] != p) {
        T val = merge(pL, pR[i + 1]);
        dfs2(v, G[v][i], g(val, v));
      }
      pL = merge(pL, f(dp[v][i], G[v][i]));
    }
  }

  void calc(int root = 0) {
    for (int i = 0; i < V; ++i) dp[i].resize(G[i].size());
    dfs1(-1, root);
    dfs2(-1, root, mi);
  }

  T solve(int v) {
    T ans = mi;
    for (int i = 0; i < G[v].size(); ++i)
      ans = merge(ans, f(dp[v][i], G[v][i]));
    return g(ans, v);
  }
};

struct T {
  ll cnt;
  bool suc;
};
struct S {
  T val;
  int len;
};

S op(S a, S b) {
  if (not a.val.suc) return a;
  a.val.cnt += b.val.cnt;
  a.val.suc &= b.val.suc;
  a.len += b.len;
  return a;
}
S e() { return {{0, true}, 0}; }

int n;
int a[300010];
vector<int> G[300010];
vector<vector<T>> dp;

const int root = 0;

T dfs1(int p, int v) {
  int ch = G[v].size();
  if (v != root) ch--;
  segtree<S, op, e> seg(ch);
  int j = 0;
  for (int i = 0; i < G[v].size(); ++i) {
    if (G[v][i] == p) continue;
    dp[v][i] = dfs1(v, G[v][i]);
    seg.set(j++, {dp[v][i], 1});
  }
  T res;
  S s;
  if (a[v] > ch) {
    s = seg.all_prod();
    res.cnt = s.val.cnt + s.len;
    res.suc = s.val.suc;
    if (res.suc) res.cnt++;
  } else {
    s = seg.prod(0, a[v]);
    res.cnt = s.val.cnt + s.len;
    res.suc = false;
  }
  return res;
}

void dfs2(int p, int v, T from_par) {
  for (int i = 0; i < G[v].size(); ++i) {
    if (G[v][i] == p) {
      dp[v][i] = from_par;
      break;
    }
  }
  int ch = G[v].size() - 1;
  vector<S> tmp(G[v].size());
  rep(i, G[v].size()) tmp[i] = {dp[v][i], 1};
  segtree<S, op, e> seg(tmp);
  for (int i = 0; i < G[v].size(); ++i) {
    if (G[v][i] == p) continue;
    T res;
    S s;
    if (a[v] > ch) {
      s = op(seg.prod(0, i), seg.prod(i + 1, G[v].size()));
      res.cnt = s.val.cnt + s.len;
      res.suc = s.val.suc;
      if (res.suc) res.cnt++;
    } else {
      if (a[v] < i) {
        s = seg.prod(0, a[v]);
      } else {
        s = op(seg.prod(0, i), seg.prod(i + 1, a[v] + 1));
      }
      res.cnt = s.val.cnt + s.len;
      res.suc = false;
    }
    dfs2(v, G[v][i], res);
  }
}

T calc(int v) {
  int ch = G[v].size();
  vector<S> tmp(G[v].size());
  rep(i, G[v].size()) tmp[i] = {dp[v][i], 1};
  segtree<S, op, e> seg(tmp);
  T res;
  S s;
  if (a[v] > ch) {
    s = seg.all_prod();
    res.cnt = s.val.cnt + s.len;
    res.suc = s.val.suc;
    if (res.suc) res.cnt++;
  } else {
    s = seg.prod(0, a[v]);
    res.cnt = s.val.cnt + s.len;
    res.suc = false;
  }
  return res;
}

void solve() {
  cin >> n;
  rep(i, n) cin >> a[i];
  rep(i, n - 1) {
    int u, v;
    cin >> u >> v;
    u--, v--;
    G[u].push_back(v);
    G[v].push_back(u);
  }
  rep(i, n) sort(all(G[i]));
  dp.resize(n);
  rep(i, n) dp[i].resize(G[i].size());
  T ans0;
  ans0 = dfs1(-1, root);
  cout << ans0.cnt << "\n";

  dfs2(-1, 0, {0, true});
  REP(i, 1, n) cout << calc(i).cnt << "\n";
}

int main() { solve(); }
accuracy: 1
time_ms: 320
memory_kb: 79464
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;


template<typename F>
struct FixPoint : F{
  FixPoint(F&& f):F(forward<F>(f)){}
  template<typename... Args>
  decltype(auto) operator()(Args&&... args) const{
    return F::operator()(*this,forward<Args>(args)...);
  }
};
template<typename F>
inline decltype(auto) MFP(F&& f){
  return FixPoint<F>{forward<F>(f)};
}

//INSERT ABOVE HERE
signed main(){
  Int n;
  cin>>n;
  vector<Int> as(n);
  for(Int i=0;i<n;i++) cin>>as[i];

  vector< vector<Int> > G(n);
  for(Int i=1;i<n;i++){
    Int u,v;
    cin>>u>>v;
    u--;v--;
    G[u].emplace_back(v);
    G[v].emplace_back(u);
  }

  for(Int i=0;i<n;i++)
    sort(G[i].begin(),G[i].end());

  // dead?, #step
  using P = pair<Int, Int>;
  vector< vector<P> > dp(n);

  auto dfs1=
    MFP([&](auto dfs,Int v,Int p)->P{
          for(Int u:G[v]){
            if(u==p) continue;
            auto res=dfs(u,v);
            dp[v].emplace_back(res);
          }
          if(as[v]==0) return P(1,0);

          Int num=as[v]-1,idx=0;
          Int dead=0,step=1;
          for(Int u:G[v]){
            if(u==p) continue;
            step+=dp[v][idx].second;
            if(dp[v][idx].first){
              dead=1;
              break;
            }
            if(num==0){
              dead=1;
              break;
            }
            num--;
            step++;
            idx++;
          }
          return P(dead,step);
        });
  dfs1(0,-1);

  //assert(*min_element(as.begin(),as.end())>0);

  vector<Int> ans(n,-1);
  MFP([&](auto dfs,Int v,Int p,P f)->void{
        if(as[v]==0){
          ans[v]=0;
          for(Int u:G[v]){
            if(u==p) continue;
            dfs(u,v,P(1,0));
          }
          return;
        }

        // find ans[v]
        vector<Int> to;
        for(Int u:G[v]){
          if(u==p) continue;
          to.emplace_back(u);
        }

        Int dead=0,step=1;
        Int num=as[v]-1;

        Int flg_for_check=0;
        auto check=
          [&](){
            if(dead) return;
            if(p<0) return;
            if(flg_for_check) return;
            flg_for_check=1;
            dead|=f.first;
            step+=f.second;

            // up from par
            if(dead||num==0){
              dead=1;
              return;
            }
            num--;
            step++;
          };

        for(Int i=0;i<(Int)to.size();i++){
          if(p<to[i]) check();
          if(dead) break;

          step+=dp[v][i].second;
          if(dp[v][i].first||num==0){
            dead=1;
            break;
          }
          num--;
          step++;
        }
        check();

        ans[v]=step;

        // call child
        for(Int u:G[v]){
          if(u==p) continue;

          flg_for_check=0;
          dead=0;step=1;num=as[v]-1;

          for(Int i=0;i<(Int)to.size();i++){
            if(p<to[i]) check();
            if(dead) break;

            if(to[i]==u) continue;

            step+=dp[v][i].second;
            if(dp[v][i].first||num==0){
              dead=1;
              break;
            }
            num--;
            step++;
          }

          check();
          dfs(u,v,P(dead,step));
        }
      })(0,-1,P(0,0));

  for(Int i=0;i<n;i++) cout<<ans[i]<<"\n";
  cout<<flush;
  return 0;
}
accuracy: 1
time_ms: 1860
memory_kb: 47252
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <stdio.h>
using namespace std;
#define int long long
int MOD = 1000000007;
vector<vector<int> > g;
vector<int> A;
vector<vector<int> > dp;
vector<vector<int> > fail;
vector<int> fi;
vector<int> se;
vector<int> fi_sum;
vector<int> se_sum;
vector<int> sum;
pair<int, int> dfs1(int a, int p) {

	dp[a].resize(g[a].size(), 0);
	fail[a].resize(g[a].size(), 0);
	int f = 0;
	int step = 0;
	int t = 1;
	if (t > A[a]) {
		f = 1;
	}
	if (f == 0) {
		step++;
	}
	for (int i = 0; i < g[a].size(); i++) {
		if (g[a][i] != p) {
			pair<int, int> p = dfs1(g[a][i], a);
			dp[a][i] = p.first;
			if (f == 0) {
				step += dp[a][i];
			}
			fail[a][i] = p.second;
			f |= p.second;
			t++;
			if (t > A[a]) {
				f = 1;
			}
			if (f == 0) {
				step++;
			}
		}
	}
	return make_pair(step, f);
}

void dfs2(int a, int p, int j) {
	int idx = -1;
	for (int i = 0; i < g[a].size(); i++) {
		if (g[a][i] == p) {
			idx = i;
		}
	}
	if (idx >= 0) {
		fail[a][idx] = 0;
		if (fi[p] == -1) {

			if (j < A[p]) {
				dp[a][idx] = sum[p] - dp[p][j];
				if (A[p] < (int)g[p].size()) {
					dp[a][idx] += dp[p][A[p]];
					/*if (fail[p][A[p]]) {
						fail[a][idx] = 1;
						dp[a][idx] += A[p] - 1;
					}
					else {
						dp[a][idx] += A[p];
					}*/
					dp[a][idx] += A[p];
					fail[a][idx] = 1;
				}
				else {
					dp[a][idx] += (int)g[p].size();
				}

			}
			else {
				dp[a][idx] = sum[p] + A[p];
				fail[a][idx] = 1;
			}
		}
		else {
			if (j < fi[p]) {
				dp[a][idx] = fi_sum[p] - dp[p][j];
				dp[a][idx] += fi[p];
				fail[a][idx] = 1;
			}
			else if (j == fi[p]) {
				if (se[p] == -1) {
					dp[a][idx] = sum[p] - dp[p][j];
					if (A[p] < (int)g[p].size()) {
						dp[a][idx] += dp[p][A[p]];
						/*if (fail[p][A[p]]) {
							fail[a][idx] = 1;
							dp[a][idx] += A[p] - 1;
						}
						else {
							dp[a][idx] += A[p];
						}*/
						dp[a][idx] += A[p];
						fail[a][idx] = 1;
					}
					else {
						dp[a][idx] += (int)g[p].size();
					}
				}
				else {
					dp[a][idx] = se_sum[p] - dp[p][j];
					dp[a][idx] += se[p];
					fail[a][idx] = 1;
				}
			}
			else {
				dp[a][idx] = fi_sum[p];
				dp[a][idx] += fi[p] + 1;
				fail[a][idx] = 1;
			}
		}
	}
	fi[a] = -1;
	se[a] = -1;
	sum[a] = 0;
	for (int i = 0; i < min(A[a], (int)g[a].size()); i++) {
		if (fail[a][i] == 1) {
			if (fi[a] == -1) {
				fi[a] = i;
				fi_sum[a] = sum[a] + dp[a][i];
			}
			else if (se[a] == -1) {
				se[a] = i;
				se_sum[a] = sum[a] + dp[a][i];
			}
		}
		sum[a] += dp[a][i];
	}



	for (int i = 0; i < g[a].size(); i++) {
		if (g[a][i] != p) {
			dfs2(g[a][i], a, i);
		}
	}
}
signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N;
	cin >> N;
	A.resize(N);
	dp.resize(N);
	fail.resize(N);
	g.resize(N);
	fi.resize(N);
	se.resize(N);
	fi_sum.resize(N);
	se_sum.resize(N);
	sum.resize(N);

	int res = 0;
	for (int i = 0; i < N; i++) {
		cin >> A[i];
	}
	int a, b;
	for (int i = 0; i < N - 1; i++) {
		cin >> a >> b; a--; b--;
		g[a].push_back(b);
		g[b].push_back(a);
	}
	for (int i = 0; i < N; i++) {
		sort(g[i].begin(), g[i].end());
	}

	dfs1(0, -1);
	dfs2(0, -1, -1);

	for (int a = 0; a < N; a++) {
		int f = 0;
		int step = 0;
		int t = 1;
		if (t > A[a]) {
			f = 1;
		}
		if (f == 0) {
			step++;
		}
		for (int i = 0; i < g[a].size(); i++) {
			if (f == 0) {
				step += dp[a][i];
			}
			f |= fail[a][i];
			t++;
			if (t > A[a]) {
				f = 1;
			}
			if (f == 0) {
				step++;
			}
		}
		cout << step << endl;

	}
}
accuracy: 1
time_ms: 680
memory_kb: 75120
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <stdio.h>
using namespace std;
#define int long long
int MOD = 1000000007;
vector<vector<int> > g;
vector<int> A;
vector<vector<int> > dp;
vector<vector<int> > fail;
vector<int> fi;
vector<int> se;
vector<int> fi_sum;
vector<int> se_sum;
vector<int> sum;
pair<int, int> dfs1(int a, int p) {

	dp[a].resize(g[a].size(), 0);
	fail[a].resize(g[a].size(), 0);
	int f = 0;
	int step = 0;
	int t = 1;
	if (t > A[a]) {
		f = 1;
	}
	if (f == 0) {
		step++;
	}
	for (int i = 0; i < g[a].size(); i++) {
		if (g[a][i] != p) {
			pair<int, int> p = dfs1(g[a][i], a);
			dp[a][i] = p.first;
			if (f == 0) {
				step += dp[a][i];
			}
			fail[a][i] = p.second;
			f |= p.second;
			t++;
			if (t > A[a]) {
				f = 1;
			}
			if (f == 0) {
				step++;
			}
		}
	}
	return make_pair(step, f);
}

void dfs2(int a, int p, int j) {
	int idx = -1;
	for (int i = 0; i < g[a].size(); i++) {
		if (g[a][i] == p) {
			idx = i;
		}
	}
	if (idx >= 0) {
		fail[a][idx] = 0;
		if (fi[p] == -1) {

			if (j < A[p]) {
				dp[a][idx] = sum[p] - dp[p][j];
				if (A[p] < (int)g[p].size()) {
					dp[a][idx] += dp[p][A[p]];
					/*if (fail[p][A[p]]) {
						fail[a][idx] = 1;
						dp[a][idx] += A[p] - 1;
					}
					else {
						dp[a][idx] += A[p];
					}*/
					dp[a][idx] += A[p];
					fail[a][idx] = 1;
				}
				else {
					dp[a][idx] += (int)g[p].size();
				}

			}
			else {
				dp[a][idx] = sum[p] + A[p];
				fail[a][idx] = 1;
			}
		}
		else {
			if (j < fi[p]) {
				dp[a][idx] = fi_sum[p] - dp[p][j];
				dp[a][idx] += fi[p];
				fail[a][idx] = 1;
			}
			else if (j == fi[p]) {
				if (se[p] == -1) {
					dp[a][idx] = sum[p] - dp[p][j];
					if (A[p] < (int)g[p].size()) {
						dp[a][idx] += dp[p][A[p]];
						/*if (fail[p][A[p]]) {
							fail[a][idx] = 1;
							dp[a][idx] += A[p] - 1;
						}
						else {
							dp[a][idx] += A[p];
						}*/
						dp[a][idx] += A[p];
						fail[a][idx] = 1;
					}
					else {
						dp[a][idx] += (int)g[p].size();
					}
				}
				else {
					dp[a][idx] = se_sum[p] - dp[p][j];
					dp[a][idx] += se[p];
					fail[a][idx] = 1;
				}
			}
			else {
				dp[a][idx] = fi_sum[p];
				dp[a][idx] += fi[p] + 1;
				fail[a][idx] = 1;
			}
		}
	}
	fi[a] = -1;
	se[a] = -1;
	sum[a] = 0;
	for (int i = 0; i < min(A[a], (int)g[a].size()); i++) {
		if (fail[a][i] == 1) {
			if (fi[a] == -1) {
				fi[a] = i;
				fi_sum[a] = sum[a] + dp[a][i];
			}
			else if (se[a] == -1) {
				se[a] = i;
				se_sum[a] = sum[a] + dp[a][i];
			}
		}
		sum[a] += dp[a][i];
	}



	for (int i = 0; i < g[a].size(); i++) {
		if (g[a][i] != p) {
			dfs2(g[a][i], a, i);
		}
	}
}
signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N;
	cin >> N;
	A.resize(N);
	dp.resize(N);
	fail.resize(N);
	g.resize(N);
	fi.resize(N);
	se.resize(N);
	fi_sum.resize(N);
	se_sum.resize(N);
	sum.resize(N);

	int res = 0;
	for (int i = 0; i < N; i++) {
		cin >> A[i];
	}
	int a, b;
	for (int i = 0; i < N - 1; i++) {
		cin >> a >> b; a--; b--;
		g[a].push_back(b);
		g[b].push_back(a);
	}
	for (int i = 0; i < N; i++) {
		sort(g[i].begin(), g[i].end());
	}

	dfs1(0, -1);
	dfs2(0, -1, -1);

	for (int a = 0; a < N; a++) {
		int f = 0;
		int step = 0;
		int t = 1;
		if (t > A[a]) {
			f = 1;
		}
		if (f == 0) {
			step++;
		}
		for (int i = 0; i < g[a].size(); i++) {
			if (f == 0) {
				step += dp[a][i];
			}
			f |= fail[a][i];
			t++;
			if (t > A[a]) {
				f = 1;
			}
			if (f == 0) {
				step++;
			}
		}
		cout << step << endl;

	}
}
accuracy: 1
time_ms: 670
memory_kb: 75208
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <stdio.h>
using namespace std;
#define int long long
int MOD = 1000000007;
vector<vector<int> > g;
vector<int> A;
vector<vector<int> > dp;
vector<vector<int> > fail;
vector<int> fi;
vector<int> se;
vector<int> fi_sum;
vector<int> se_sum;
vector<int> sum;
pair<int, int> dfs1(int a, int p) {

	dp[a].resize(g[a].size(), 0);
	fail[a].resize(g[a].size(), 0);
	int f = 0;
	int step = 0;
	int t = 1;
	if (t > A[a]) {
		f = 1;
	}
	if (f == 0) {
		step++;
	}
	for (int i = 0; i < g[a].size(); i++) {
		if (g[a][i] != p) {
			pair<int, int> p = dfs1(g[a][i], a);
			dp[a][i] = p.first;
			if (f == 0) {
				step += dp[a][i];
			}
			fail[a][i] = p.second;
			f |= p.second;
			t++;
			if (t > A[a]) {
				f = 1;
			}
			if (f == 0) {
				step++;
			}
		}
	}
	return make_pair(step, f);
}

void dfs2(int a, int p, int j) {
	int idx = -1;
	for (int i = 0; i < g[a].size(); i++) {
		if (g[a][i] == p) {
			idx = i;
		}
	}
	if (idx >= 0) {
		fail[a][idx] = 0;
		if (fi[p] == -1) {

			if (j < A[p]) {
				dp[a][idx] = sum[p] - dp[p][j];
				if (A[p] < (int)g[p].size()) {
					dp[a][idx] += dp[p][A[p]];
					/*if (fail[p][A[p]]) {
						fail[a][idx] = 1;
						dp[a][idx] += A[p] - 1;
					}
					else {
						dp[a][idx] += A[p];
					}*/
					dp[a][idx] += A[p];
					fail[a][idx] = 1;
				}
				else {
					dp[a][idx] += (int)g[p].size();
				}

			}
			else {
				dp[a][idx] = sum[p] + A[p];
				fail[a][idx] = 1;
			}
		}
		else {
			if (j < fi[p]) {
				dp[a][idx] = fi_sum[p] - dp[p][j];
				dp[a][idx] += fi[p];
				fail[a][idx] = 1;
			}
			else if (j == fi[p]) {
				if (se[p] == -1) {
					dp[a][idx] = sum[p] - dp[p][j];
					if (A[p] < (int)g[p].size()) {
						dp[a][idx] += dp[p][A[p]];
						/*if (fail[p][A[p]]) {
							fail[a][idx] = 1;
							dp[a][idx] += A[p] - 1;
						}
						else {
							dp[a][idx] += A[p];
						}*/
						dp[a][idx] += A[p];
						fail[a][idx] = 1;
					}
					else {
						dp[a][idx] += (int)g[p].size();
					}
				}
				else {
					dp[a][idx] = se_sum[p] - dp[p][j];
					dp[a][idx] += se[p];
					fail[a][idx] = 1;
				}
			}
			else {
				dp[a][idx] = fi_sum[p];
				dp[a][idx] += fi[p] + 1;
				fail[a][idx] = 1;
			}
		}
	}
	fi[a] = -1;
	se[a] = -1;
	sum[a] = 0;
	for (int i = 0; i < min(A[a], (int)g[a].size()); i++) {
		if (fail[a][i] == 1) {
			if (fi[a] == -1) {
				fi[a] = i;
				fi_sum[a] = sum[a] + dp[a][i];
			}
			else if (se[a] == -1) {
				se[a] = i;
				se_sum[a] = sum[a] + dp[a][i];
			}
		}
		sum[a] += dp[a][i];
	}



	for (int i = 0; i < g[a].size(); i++) {
		if (g[a][i] != p) {
			dfs2(g[a][i], a, i);
		}
	}
}
signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N;
	cin >> N;
	A.resize(N);
	dp.resize(N);
	fail.resize(N);
	g.resize(N);
	fi.resize(N);
	se.resize(N);
	fi_sum.resize(N);
	se_sum.resize(N);
	sum.resize(N);

	int res = 0;
	for (int i = 0; i < N; i++) {
		cin >> A[i];
	}
	int a, b;
	for (int i = 0; i < N - 1; i++) {
		cin >> a >> b; a--; b--;
		g[a].push_back(b);
		g[b].push_back(a);
	}
	for (int i = 0; i < N; i++) {
		sort(g[i].begin(), g[i].end());
	}

	dfs1(0, -1);
	dfs2(0, -1, -1);

	for (int a = 0; a < N; a++) {
		int f = 0;
		int step = 0;
		int t = 1;
		if (t > A[a]) {
			f = 1;
		}
		if (f == 0) {
			step++;
		}
		for (int i = 0; i < g[a].size(); i++) {
			if (f == 0) {
				step += dp[a][i];
			}
			f |= fail[a][i];
			t++;
			if (t > A[a]) {
				f = 1;
			}
			if (f == 0) {
				step++;
			}
		}
		cout << step << endl;

	}
}
accuracy: 1
time_ms: 670
memory_kb: 75044
final_rank: 4

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 300010

vector<int> G[SIZE];
int A1[SIZE], A2[SIZE];

pair<bool,int> res1[SIZE], res2[SIZE];

void dfs1(int now, int back = -1) {

  bool dead = A1[now] <= 0;
  int step = A1[now] > 0;

  A1[now] -= 1;

  for(int to : G[now]) {
    if (to == back) continue;

    dfs1(to, now);

    if(!dead) step += res1[to].second;
    dead |= res1[to].first;

    dead |= A1[now] <= 0;
    A1[now] -= 1;
    if(!dead) step++;
  }

  res1[now] = {dead, step};
}

int ans[SIZE];

void dfs2(int now, int back = -1) {
  set<int> deadList;
  map<int,int> idx;

  vector<pair<int,pair<bool,int> > > vec;

  for (int to : G[now]) {
    if (to == back)
      vec.push_back({to, res2[to]});
    else
      vec.push_back({to, res1[to]});
  }

  sort(vec.begin(), vec.end());

  vector<int> sum(G[now].size());

  for(int i=0; i<vec.size(); i++){
    idx[vec[i].first] = i;

    if (vec[i].second.first)
      deadList.insert(i);

    sum[i] = vec[i].second.second;
    if (i > 0) sum[i] += sum[i-1];
  }

  int tmpA = A2[now];

  ans[now] = tmpA > 0;
  tmpA--;

  debug(now);
  debug(res2[0]);
  debug(vec);

  for(int i=0; i<vec.size(); i++){
    if (tmpA < 0) break;
    ans[now] += vec[i].second.second;
    if (vec[i].second.first) break;
    if(tmpA <= 0) break;
    tmpA--;
    ans[now]++;
  }

  for(int to : G[now]) {
    if (to == back) continue;

    auto it = deadList.begin();

    if (it != deadList.end() && *it == idx[to]) it++;

    int deadLine = INF;

    if(it != deadList.end()){
      deadLine = *it;
    }

    int x = A2[now] - 1;

    if(x >= idx[to]) x++;

    deadLine = min(deadLine, x);

    int step = 0;
    if (deadLine >= (int)G[now].size())
      step = sum[G[now].size()-1] - vec[idx[to]].second.second;
    else if (deadLine < 0)
      step = 0;
    else
      step = sum[deadLine] - vec[idx[to]].second.second * (deadLine >= idx[to]);

    res2[now] = {deadLine < (int)G[now].size(), step + 1 + min(deadLine, (int)G[now].size()) - (deadLine >= idx[to])};

    dfs2(to, now);
  }
}


int N, A[SIZE];

int main(){

  scanf("%d", &N);

  for(int i=0; i<N; i++) {
    scanf("%d", A+i);
    A1[i] = A[i];
    A2[i] = A[i];
  }

  for(int i=0; i<N-1; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    u--; v--;

    G[u].push_back(v);
    G[v].push_back(u);
  }

  for(int i=0; i<N; i++)
    sort(G[i].begin(), G[i].end());

  dfs1(0);
  dfs2(0);

  for(int i=0; i<N; i++) {
    printf("%d\n", ans[i]);
  }

  return 0;
}
accuracy: 1
time_ms: 320
memory_kb: 51796
final_rank: 1

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 300010

vector<int> G[SIZE];
int A1[SIZE], A2[SIZE];

pair<bool,int> res1[SIZE], res2[SIZE];

void dfs1(int now, int back = -1) {

  debug(now);
  debug(A1[now]);

  bool dead = A1[now] <= 0;
  int step = A1[now] > 0;

  A1[now] -= 1;

  for(int to : G[now]) {
    if (to == back) continue;

    dfs1(to, now);

    if(!dead) step += res1[to].second;
    dead |= res1[to].first;

    dead |= A1[now] <= 0;
    A1[now] -= 1;
    if(!dead) step++;
  }

  debug(now);
  debug(dead);

  res1[now] = {dead, step};
}

int ans[SIZE];

void dfs2(int now, int back = -1) {
  set<int> deadList;
  map<int,int> idx;

  vector<pair<int,pair<bool,int> > > vec;

  for (int to : G[now]) {
    if (to == back)
      vec.push_back({to, res2[to]});
    else
      vec.push_back({to, res1[to]});
  }

  sort(vec.begin(), vec.end());

  vector<int> sum(G[now].size());

  for(int i=0; i<vec.size(); i++){
    idx[vec[i].first] = i;

    if (vec[i].second.first)
      deadList.insert(i);

    sum[i] = vec[i].second.second;
    if (i > 0) sum[i] += sum[i-1];
  }

  int tmpA = A2[now];

  ans[now] = tmpA > 0;
  tmpA--;

  debug(now);

  for(int i=0; i<vec.size(); i++){
    debug(vec[i]);
    if (tmpA < 0) break;
    ans[now] += vec[i].second.second;
    if (vec[i].second.first) break;
    if(tmpA <= 0) break;
    tmpA--;
    ans[now]++;
  }

  for(int to : G[now]) {
    if (to == back) continue;

    auto it = deadList.begin();

    if (it != deadList.end() && *it == idx[to]) it++;

    int deadLine = INF;

    if(it != deadList.end()){
      deadLine = *it;
    }

    //debug(now); debug(to); debug(deadLine);

    int x = A2[now] - 1;

    if(x >= idx[to]) x++;

    deadLine = min(deadLine, x);

    int step = 0;
    if (deadLine >= G[now].size())
      step = sum[G[now].size()-1] - vec[idx[to]].second.second;
    else if (deadLine < 0)
      step = 0;
    else
      step = sum[deadLine] - vec[idx[to]].second.second * (deadLine >= idx[to]);

    debug(now);
    debug(deadLine - (deadLine >= idx[to]));
    res2[now] = {deadLine < G[now].size(), step + 1 + min(deadLine, (int)G[now].size()) - (deadLine >= idx[to])};

    dfs2(to, now);
  }
}


int N, A[SIZE];

int main(){

  scanf("%d", &N);

  for(int i=0; i<N; i++) {
    scanf("%d", A+i);
    A1[i] = A[i];
    A2[i] = A[i];
  }

  for(int i=0; i<N-1; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    u--; v--;

    G[u].push_back(v);
    G[v].push_back(u);
  }

  for(int i=0; i<N; i++)
    sort(G[i].begin(), G[i].end());

  if (N <= 1000) {
    for(int i=0; i<N; i++) {
      dfs1(i);
      ans[i] = res1[i].second;
      for(int j=0; j<N; j++) A1[j] = A[j];
    }
  } else {
    //srand(time(NULL));
    //int r = rand() % N;
    int r = 0;
  
    dfs1(r);
    dfs2(r);
  }
  
  for(int i=0; i<N; i++) {
    printf("%d\n", ans[i]);
  }

  return 0;
}
accuracy: 0.44047619047619047
time_ms: 280
memory_kb: 29392
final_rank: 17

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 300010

vector<int> G[SIZE];
int A1[SIZE], A2[SIZE];

pair<bool,int> res1[SIZE], res2[SIZE];

void dfs1(int now, int back = -1) {

  debug(now);
  debug(A1[now]);

  bool dead = A1[now] <= 0;
  int step = A1[now] > 0;

  A1[now] -= 1;

  for(int to : G[now]) {
    if (to == back) continue;

    dfs1(to, now);

    if(!dead) step += res1[to].second;
    dead |= res1[to].first;

    dead |= A1[now] <= 0;
    A1[now] -= 1;
    if(!dead) step++;
  }

  debug(now);
  debug(dead);

  res1[now] = {dead, step};
}

int ans[SIZE];

void dfs2(int now, int back = -1) {
  set<int> deadList;
  map<int,int> idx;

  vector<pair<int,pair<bool,int> > > vec;

  for (int to : G[now]) {
    if (to == back)
      vec.push_back({to, res2[to]});
    else
      vec.push_back({to, res1[to]});
  }

  sort(vec.begin(), vec.end());

  vector<int> sum(G[now].size());

  for(int i=0; i<vec.size(); i++){
    idx[vec[i].first] = i;

    if (vec[i].second.first)
      deadList.insert(i);

    sum[i] = vec[i].second.second;
    if (i > 0) sum[i] += sum[i-1];
  }

  int tmpA = A2[now];

  ans[now] = tmpA > 0;
  tmpA--;

  debug(now);

  for(int i=0; i<vec.size(); i++){
    debug(vec[i]);
    if (tmpA < 0) break;
    ans[now] += vec[i].second.second;
    if (vec[i].second.first) break;
    if(tmpA <= 0) break;
    tmpA--;
    ans[now]++;
  }

  for(int to : G[now]) {
    if (to == back) continue;

    auto it = deadList.begin();

    if (it != deadList.end() && *it == idx[to]) it++;

    int deadLine = INF;

    if(it != deadList.end()){
      deadLine = *it;
    }

    //debug(now); debug(to); debug(deadLine);

    int x = A2[now] - 1;

    if(x >= idx[to]) x++;

    deadLine = min(deadLine, x);

    int step = 0;
    if (deadLine >= G[now].size())
      step = sum[G[now].size()-1] - vec[idx[to]].second.second;
    else if (deadLine < 0)
      step = 0;
    else
      step = sum[deadLine] - vec[idx[to]].second.second * (deadLine >= idx[to]);

    debug(now);
    debug(deadLine - (deadLine >= idx[to]));
    res2[now] = {deadLine < G[now].size(), step + 1 + min(deadLine, (int)G[now].size()) - (deadLine >= idx[to])};

    dfs2(to, now);
  }
}


int N, A[SIZE];

int main(){

  scanf("%d", &N);

  for(int i=0; i<N; i++) {
    scanf("%d", A+i);
    A1[i] = A[i];
    A2[i] = A[i];
  }

  for(int i=0; i<N-1; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    u--; v--;

    G[u].push_back(v);
    G[v].push_back(u);
  }

  for(int i=0; i<N; i++)
    sort(G[i].begin(), G[i].end());

  //srand(time(NULL));
  //int r = rand() % N;
  int r = 0;
  
  dfs1(r);
  dfs2(r);

  for(int i=0; i<N; i++) {
    printf("%d\n", ans[i]);
  }

  return 0;
}
accuracy: 0.44047619047619047
time_ms: 290
memory_kb: 29392
final_rank: 19

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 300010

vector<int> G[SIZE];
int A1[SIZE], A2[SIZE];

pair<bool,int> res1[SIZE], res2[SIZE];

void dfs1(int now, int back = -1) {

  debug(now);
  debug(A1[now]);

  bool dead = A1[now] <= 0;
  int step = A1[now] > 0;

  A1[now] -= 1;

  for(int to : G[now]) {
    if (to == back) continue;

    dfs1(to, now);

    if(!dead) step += res1[to].second;
    dead |= res1[to].first;

    dead |= A1[now] <= 0;
    A1[now] -= 1;
    if(!dead) step++;
  }

  debug(now);
  debug(dead);

  res1[now] = {dead, step};
}

int ans[SIZE];

void dfs2(int now, int back = -1) {
  set<int> deadList;
  map<int,int> idx;

  vector<pair<int,pair<bool,int> > > vec;

  for (int to : G[now]) {
    if (to == back)
      vec.push_back({to, res2[to]});
    else
      vec.push_back({to, res1[to]});
  }

  sort(vec.begin(), vec.end());

  vector<int> sum(G[now].size());

  for(int i=0; i<vec.size(); i++){
    idx[vec[i].first] = i;

    if (vec[i].second.first)
      deadList.insert(i);

    sum[i] = vec[i].second.second;
    if (i > 0) sum[i] += sum[i-1];
  }

  int tmpA = A2[now];

  ans[now] = tmpA > 0;
  tmpA--;

  debug(now);

  for(int i=0; i<vec.size(); i++){
    debug(vec[i]);
    if (tmpA < 0) break;
    ans[now] += vec[i].second.second;
    if (vec[i].second.first) break;
    if(tmpA <= 0) break;
    tmpA--;
    ans[now]++;
  }

  for(int to : G[now]) {
    if (to == back) continue;

    auto it = deadList.begin();

    if (it != deadList.end() && *it == idx[to]) it++;

    int deadLine = INF;

    if(it != deadList.end()){
      deadLine = *it;
    }

    //debug(now); debug(to); debug(deadLine);

    int x = A2[now] - 1;

    if(x >= idx[to]) x++;

    deadLine = min(deadLine, x);

    int step = 0;
    if (deadLine >= G[now].size())
      step = sum[G[now].size()-1] - vec[idx[to]].second.second;
    else if (deadLine < 0)
      step = 0;
    else
      step = sum[deadLine] - vec[idx[to]].second.second * (deadLine >= idx[to]);

    debug(now);
    debug(deadLine - (deadLine >= idx[to]));
    res2[now] = {deadLine < G[now].size(), step + 1 + min(deadLine, (int)G[now].size()) - (deadLine >= idx[to])};

    dfs2(to, now);
  }
}


int N, A[SIZE];

int main(){

  scanf("%d", &N);

  for(int i=0; i<N; i++) {
    scanf("%d", A+i);
    A1[i] = A[i];
    A2[i] = A[i];
  }

  for(int i=0; i<N-1; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    u--; v--;

    G[u].push_back(v);
    G[v].push_back(u);
  }

  for(int i=0; i<N; i++)
    sort(G[i].begin(), G[i].end());

  srand(time(NULL));
  int r = rand() % N;

  dfs1(r);
  dfs2(r);

  for(int i=0; i<N; i++) {
    printf("%d\n", ans[i]);
  }

  return 0;
}
accuracy: 0.9285714285714286
time_ms: 310
memory_kb: 52080
final_rank: 14

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 300010

vector<int> G[SIZE];
int A1[SIZE], A2[SIZE];

pair<bool,int> res1[SIZE], res2[SIZE];

void dfs1(int now, int back = -1) {

  debug(now);
  debug(A1[now]);

  bool dead = A1[now] <= 0;
  int step = A1[now] > 0;

  A1[now] -= 1;

  for(int to : G[now]) {
    if (to == back) continue;

    dfs1(to, now);

    if(!dead) step += res1[to].second;
    dead |= res1[to].first;

    dead |= A1[now] <= 0;
    A1[now] -= 1;
    if(!dead) step++;
  }

  debug(now);
  debug(dead);

  res1[now] = {dead, step};
}

int ans[SIZE];

void dfs2(int now, int back = -1) {
  set<int> deadList;
  map<int,int> idx;

  vector<pair<int,pair<bool,int> > > vec;

  for (int to : G[now]) {
    if (to == back)
      vec.push_back({to, res2[to]});
    else
      vec.push_back({to, res1[to]});
  }

  sort(vec.begin(), vec.end());

  vector<int> sum(G[now].size());

  for(int i=0; i<vec.size(); i++){
    idx[vec[i].first] = i;

    if (vec[i].second.first)
      deadList.insert(i);

    sum[i] = vec[i].second.second;
    if (i > 0) sum[i] += sum[i-1];
  }

  int tmpA = A2[now];

  ans[now] = tmpA > 0;
  tmpA--;

  debug(now);

  for(int i=0; i<vec.size(); i++){
    debug(vec[i]);
    if (tmpA < 0) break;
    ans[now] += vec[i].second.second;
    if (vec[i].second.first) break;
    if(tmpA <= 0) break;
    tmpA--;
    ans[now]++;
  }

  for(int to : G[now]) {
    if (to == back) continue;

    auto it = deadList.begin();

    if (it != deadList.end() && *it == idx[to]) it++;

    int deadLine = INF;

    if(it != deadList.end()){
      deadLine = *it;
    }

    //debug(now); debug(to); debug(deadLine);

    int x = A2[now] - 1;

    if(x >= idx[to]) x++;

    deadLine = min(deadLine, x);

    int step = 0;
    if (deadLine >= G[now].size())
      step = sum[G[now].size()-1] - vec[idx[to]].second.second;
    else if (deadLine < 0)
      step = 0;
    else
      step = sum[deadLine] - vec[idx[to]].second.second * (deadLine >= idx[to]);

    debug(now);
    debug(deadLine - (deadLine >= idx[to]));
    res2[now] = {deadLine < G[now].size(), step + 1 + min(deadLine, (int)G[now].size()) - (deadLine >= idx[to])};

    dfs2(to, now);
  }
}


int N, A[SIZE];

int main(){

  scanf("%d", &N);

  for(int i=0; i<N; i++) {
    scanf("%d", A+i);
    A1[i] = A[i];
    A2[i] = A[i];
  }

  for(int i=0; i<N-1; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    u--; v--;

    G[u].push_back(v);
    G[v].push_back(u);
  }

  for(int i=0; i<N; i++)
    sort(G[i].begin(), G[i].end());

  int r = rand() % N;

  dfs1(r);
  dfs2(r);

  for(int i=0; i<N; i++) {
    printf("%d\n", ans[i]);
  }

  return 0;
}
accuracy: 0.9285714285714286
time_ms: 310
memory_kb: 53656
final_rank: 15

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 300010

vector<int> G[SIZE];
int A1[SIZE], A2[SIZE];

pair<bool,int> res1[SIZE], res2[SIZE];

void dfs1(int now, int back = -1) {

  debug(now);
  debug(A1[now]);

  bool dead = A1[now] <= 0;
  int step = A1[now] > 0;

  A1[now] -= 1;

  for(int to : G[now]) {
    if (to == back) continue;

    dfs1(to, now);

    if(!dead) step += res1[to].second;
    dead |= res1[to].first;

    dead |= A1[now] <= 0;
    A1[now] -= 1;
    if(!dead) step++;
  }

  debug(now);
  debug(dead);

  res1[now] = {dead, step};
}

int ans[SIZE];

void dfs2(int now, int back = -1) {
  set<int> deadList;
  map<int,int> idx;

  vector<pair<int,pair<bool,int> > > vec;

  for (int to : G[now]) {
    if (to == back)
      vec.push_back({to, res2[to]});
    else
      vec.push_back({to, res1[to]});
  }

  sort(vec.begin(), vec.end());

  vector<int> sum(G[now].size());

  for(int i=0; i<vec.size(); i++){
    idx[vec[i].first] = i;

    if (vec[i].second.first)
      deadList.insert(i);

    sum[i] = vec[i].second.second;
    if (i > 0) sum[i] += sum[i-1];
  }

  int tmpA = A2[now];

  ans[now] = tmpA > 0;
  tmpA--;

  debug(now);

  for(int i=0; i<vec.size(); i++){
    debug(vec[i]);
    if (tmpA < 0) break;
    ans[now] += vec[i].second.second;
    if (vec[i].second.first) break;
    if(tmpA <= 0) break;
    tmpA--;
    ans[now]++;
  }

  for(int to : G[now]) {
    if (to == back) continue;

    auto it = deadList.begin();

    if (it != deadList.end() && *it == idx[to]) it++;

    int deadLine = INF;

    if(it != deadList.end()){
      deadLine = *it;
    }

    //debug(now); debug(to); debug(deadLine);

    int x = A2[now] - 1;

    if(x >= idx[to]) x++;

    deadLine = min(deadLine, x);

    int step = 0;
    if (deadLine >= G[now].size())
      step = sum[G[now].size()-1] - vec[idx[to]].second.second;
    else if (deadLine < 0)
      step = 0;
    else
      step = sum[deadLine] - vec[idx[to]].second.second * (deadLine >= idx[to]);

    debug(now);
    debug(deadLine - (deadLine >= idx[to]));
    res2[now] = {deadLine < G[now].size(), step + 1 + min(deadLine, (int)G[now].size()) - (deadLine >= idx[to])};

    dfs2(to, now);
  }
}


int N, A[SIZE];

int main(){

  scanf("%d", &N);

  for(int i=0; i<N; i++) {
    scanf("%d", A+i);
    A1[i] = A[i];
    A2[i] = A[i];
  }

  for(int i=0; i<N-1; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    u--; v--;

    G[u].push_back(v);
    G[v].push_back(u);
  }

  for(int i=0; i<N; i++)
    sort(G[i].begin(), G[i].end());

  /*
  for(int i=0; i<N; i++) {
    for(int j=0; j<N; j++) A1[j] = A[j];
    dfs1(i);
    ans[i] = res1[i].second;
  }
  */

  dfs1(0);
  dfs2(0);

  for(int i=0; i<N; i++) {
    printf("%d\n", ans[i]);
  }

  return 0;
}
accuracy: 0.44047619047619047
time_ms: 290
memory_kb: 29356
final_rank: 18

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
typedef pair<int, bool> sP;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef pair<ll, ll> LP;
typedef vector<ll> vec;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-5;
const ld pi = acos(-1.0);

int n;
const int mn = 300000;
int a[mn];
vector<int> G[mn];

int sz;
bool mp[mn];
int num[mn];
int g;
void dfs2(int id, int fr) {
	num[id] = 1;
	bool f = true;
	rep(j, G[id].size()) {
		int to = G[id][j];
		if (to == fr || !mp[to])continue;
		dfs2(to, id);
		num[id] += num[to];
		if (num[to] > sz / 2)f = false;
	}
	if (sz - num[id] > sz / 2)f = false;
	if (f)g = id;
}

map<P, sP> memo;
int out[mn];


int c[mn];
sP dfs(int id, int fr) {
	if (c[id] >= a[id]) {
		return { 0,false };
	}
	c[id]++;
	sP ret = { 1,true };
	rep(j, G[id].size()) {
		int to = G[id][j];
		if (to == fr)continue;
		if (!mp[to]) {
			sP p = memo[{to, id}];
			ret.first += p.first;
			ret.second = p.second;
			if (p.second == false) {
				return ret;
			}
		}
		else {
			sP p = dfs(to, id);
			ret.first += p.first;
			ret.second = p.second;
			if (p.second == false) {
				return ret;
			}
		}
		if (c[id] >= a[id])return { ret.first,false };
		c[id]++; ret.first++;
	}
	return ret;
}


vector<int> nex;
void tonex(int id, int fr) {
	nex.push_back(id);
	rep(j, G[id].size()) {
		int to = G[id][j];
		if (to == fr)continue;
		if (!mp[to])continue;
		tonex(to, id);
	}
}
queue<vector<int>> que;
void ans(vector<int> &v) {
	if (v.empty())return;
	sz = v.size();
	rep(i, v.size())mp[v[i]] = true;
	int root = v[0];
	g = root;
	dfs2(root, -1);
	root = g;
	rep(i, v.size())c[v[i]] = 0;
	bool exifalse = false;
	vector<sP> vp;
	vector<int> ids;
	rep(j, G[root].size()) {
		int to = G[root][j];
		sP p;
		if (mp[to]) {
			p = dfs(to, root);
			if (p.second == false && j<a[root]) {
				exifalse = true;
			}
			vp.push_back(p);
			ids.push_back(to);
		}
		else {
			p = memo[{to, root}];
			if (p.second == false && j<a[root]) {
				exifalse = true;
			}
			vp.push_back(p);
			ids.push_back(to);
		}
		//cout << root << " !!! " << to << " " << p.first << endl;
	}
	vector<int> rp(vp.size() + 1);
	rep(i, vp.size()) {
		rp[i + 1] = rp[i] + vp[i].first;
	}
	/*int chk = vp.size();
	if (!exifalse) {
	chk = min(chk, a[root]);
	}
	else {
	rep(i, vp.size()) {
	if (vp[i].second == false) {
	chk = i + 1; break;
	}
	}
	}*/
	/*Rep(i, chk, vp.size()) {
	int to = ids[i];
	if (mp[to]) {
	memo[{root, to}] = { rp[chk] + chk,false };
	}
	}*/
	out[root]++;
	if (a[root] == 0) {
		out[root] = 0;
		rep(i, vp.size()) {
			int to = ids[i];
			memo[{root, to}] = { 0,false };
		}
	}
	else if (!exifalse) {
		//cout << "Hello!" << endl;
		c[root] = 1;
		int chk = vp.size();
		rep(i, vp.size()) {
			//cout <<"hello "<< vp[i].first << endl;
			if (vp[i].second == false) {
				out[root] += vp[i].first;
				chk = i;
				break;
			}
			else {
				out[root] += vp[i].first;
				if (c[root] >= a[root]) {
					chk = i + 1;
					break;
				}
				c[root]++;
				out[root]++;
			}
		}
		//cout << "uoaaaa " << chk << endl;
		Rep(i, chk, vp.size()) {
			int cur = ids[i];
			if (mp[cur]) {
				//cout << root << " " << cur << " " << rp[chk] + chk << endl;
				memo[{root, cur}] = { rp[chk] + chk,false };
			}
		}
		if (chk == vp.size()) {
			rep(i, chk) {
				int to = ids[i];
				if (!mp[to])continue;
				int sum = rp[vp.size()] - vp[i].first;
				//cout << root << " " << to << " " << sum + chk << endl;
				memo[{root, to}] = { sum + chk,true };
			}
		}
		else {
			rep(i, chk) {
				int to = ids[i];
				if (!mp[to])continue;
				int sum = rp[chk + 1] - vp[i].first;
				//cout << root << " " << to << " " << sum + chk << endl;
				memo[{root, to}] = { sum + chk,false };
			}
		}
	}
	else {
		//cout << "aaaa" << endl;
		c[root] = 1;
		rep(i, vp.size()) {
			//cout << root << " ?? " << vp[i].first << ids[i]<<endl;
			//cout << vp[i].first << endl;
			if (vp[i].second == false) {
				out[root] += vp[i].first;
				//chk = i;
				break;
			}
			else {
				out[root] += vp[i].first;
				c[root]++;
				out[root]++;
			}
		}
		int chk = vp.size();
		rep(i, vp.size()) {
			if (vp[i].second == false) {
				chk = i; break;
			}
		}
		//cout << root << " " << ids[chk] << endl;
		Rep(i, chk + 1, vp.size()) {
			int cur = ids[i];
			if (!mp[cur])continue;
			//cout << root << " " << cur << " " << rp[chk+1] + chk+1 << endl;
			memo[{root, cur}] = { rp[chk + 1] + chk + 1,false };
		}
		rep(i, chk) {
			int to = ids[i];
			if (!mp[to])continue;
			int sum = rp[chk + 1] - vp[i].first;
			//cout << root << " " << to << " " << sum + chk << endl;
			memo[{root, to}] = { sum + chk,false };
		}
		c[root] = 1;
		int al = 1; bool va = true;
		rep(i, vp.size()) {
			if (i == chk)continue;
			if (vp[i].second == false) {
				al += vp[i].first;
				va = false;
				//chk = i;
				break;
			}
			else {
				al += vp[i].first;
				if (c[root] >= a[root]) {
					va = false; break;
				}
				c[root]++;
				al++;
			}
		}
		//cout << root << " " << ids[chk] << " " << al << endl;
		memo[{root, ids[chk]}] = { al,va };
	}
	rep(j, G[root].size()) {
		int to = G[root][j];
		if (!mp[to])continue;
		nex.clear();
		tonex(to, root);
		if (nex.size())que.push(nex);
	}
	rep(i, v.size())mp[v[i]] = false;
}

void solve() {
	cin >> n;
	rep(i, n) {
		cin >> a[i];
	}
	rep(i, n - 1) {
		int u, v; cin >> u >> v; u--; v--;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	vector<int> ori;
	rep(i, n) {
		sort(G[i].begin(), G[i].end());
		ori.push_back(i);
	}
	que.push(ori);
	while (!que.empty()) {
		vector<int> v = que.front(); que.pop();
		ans(v);
		//cout << "??" << endl;
	}
	rep(i, n) {
		cout << out[i] << endl;
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	//stop
	return 0;
}
accuracy: 1
time_ms: 1370
memory_kb: 66456
final_rank: 9

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
typedef pair<int, bool> sP;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef pair<ll, ll> LP;
typedef vector<ll> vec;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-5;
const ld pi = acos(-1.0);

int n;
const int mn = 300000;
int a[mn];
vector<int> G[mn];

int sz;
bool mp[mn];
int num[mn];
int g;
void dfs2(int id, int fr) {
	num[id] = 1;
	bool f = true;
	rep(j, G[id].size()) {
		int to = G[id][j];
		if (to == fr || !mp[to])continue;
		dfs2(to, id);
		num[id] += num[to];
		if (num[to] > sz / 2)f = false;
	}
	if (sz - num[id] > sz / 2)f = false;
	if (f)g = id;
}

map<P, sP> memo;
int out[mn];


int c[mn];
sP dfs(int id, int fr) {
	if (c[id] >= a[id]) {
		return { 0,false };
	}
	c[id]++;
	sP ret = { 1,true };
	rep(j, G[id].size()) {
		int to = G[id][j];
		if (to == fr)continue;
		if (!mp[to]) {
			sP p = memo[{to, id}];
			ret.first += p.first;
			ret.second = p.second;
			if (p.second == false) {
				return ret;
			}
		}
		else {
			sP p = dfs(to, id);
			ret.first += p.first;
			ret.second = p.second;
			if (p.second == false) {
				return ret;
			}
		}
		if (c[id] >= a[id])return { ret.first,false };
		c[id]++; ret.first++;
	}
	return ret;
}


vector<int> nex;
void tonex(int id, int fr) {
	nex.push_back(id);
	rep(j, G[id].size()) {
		int to = G[id][j];
		if (to == fr)continue;
		if (!mp[to])continue;
		tonex(to, id);
	}
}
queue<vector<int>> que;
void ans(vector<int> &v) {
	if (v.empty())return;
	sz = v.size();
	rep(i, v.size())mp[v[i]] = true;
	int root = v[0];
	g = root;
	dfs2(root, -1);
	root = g;
	rep(i, v.size())c[v[i]] = 0;
	bool exifalse = false;
	vector<sP> vp;
	vector<int> ids;
	rep(j, G[root].size()) {
		int to = G[root][j];
		sP p;
		if (mp[to]) {
			p = dfs(to, root);
			if (p.second == false && j<a[root]) {
				exifalse = true;
			}
			vp.push_back(p);
			ids.push_back(to);
		}
		else {
			p = memo[{to, root}];
			if (p.second == false && j<a[root]) {
				exifalse = true;
			}
			vp.push_back(p);
			ids.push_back(to);
		}
		//cout << root << " !!! " << to << " " << p.first << endl;
	}
	vector<int> rp(vp.size() + 1);
	rep(i, vp.size()) {
		rp[i + 1] = rp[i] + vp[i].first;
	}
	/*int chk = vp.size();
	if (!exifalse) {
	chk = min(chk, a[root]);
	}
	else {
	rep(i, vp.size()) {
	if (vp[i].second == false) {
	chk = i + 1; break;
	}
	}
	}*/
	/*Rep(i, chk, vp.size()) {
	int to = ids[i];
	if (mp[to]) {
	memo[{root, to}] = { rp[chk] + chk,false };
	}
	}*/
	out[root]++;
	if (!exifalse) {
		//cout << "Hello!" << endl;
		c[root] = 1;
		int chk = vp.size();
		rep(i, vp.size()) {
			//cout <<"hello "<< vp[i].first << endl;
			if (vp[i].second == false) {
				out[root] += vp[i].first;
				chk = i;
				break;
			}
			else {
				out[root] += vp[i].first;
				if (c[root] >= a[root]) {
					chk = i + 1;
					break;
				}
				c[root]++;
				out[root]++;
			}
		}
		//cout << "uoaaaa " << chk << endl;
		Rep(i, chk, vp.size()) {
			int cur = ids[i];
			if (mp[cur]) {
				//cout << root << " " << cur << " " << rp[chk] + chk << endl;
				memo[{root, cur}] = { rp[chk] + chk,false };
			}
		}
		if (chk == vp.size()) {
			rep(i, chk) {
				int to = ids[i];
				if (!mp[to])continue;
				int sum = rp[vp.size()] - vp[i].first;
				//cout << root << " " << to << " " << sum + chk << endl;
				memo[{root, to}] = { sum + chk,true };
			}
		}
		else {
			rep(i, chk) {
				int to = ids[i];
				if (!mp[to])continue;
				int sum = rp[chk + 1] - vp[i].first;
				//cout << root << " " << to << " " << sum + chk << endl;
				memo[{root, to}] = { sum + chk,false };
			}
		}
	}
	else {
		//cout << "aaaa" << endl;
		c[root] = 1;
		rep(i, vp.size()) {
			//cout << root << " ?? " << vp[i].first << ids[i]<<endl;
			//cout << vp[i].first << endl;
			if (vp[i].second == false) {
				out[root] += vp[i].first;
				//chk = i;
				break;
			}
			else {
				out[root] += vp[i].first;
				c[root]++;
				out[root]++;
			}
		}
		int chk = vp.size();
		rep(i, vp.size()) {
			if (vp[i].second == false) {
				chk = i; break;
			}
		}
		//cout << root << " " << ids[chk] << endl;
		Rep(i, chk + 1, vp.size()) {
			int cur = ids[i];
			if (!mp[cur])continue;
			//cout << root << " " << cur << " " << rp[chk+1] + chk+1 << endl;
			memo[{root, cur}] = { rp[chk + 1] + chk + 1,false };
		}
		rep(i, chk) {
			int to = ids[i];
			if (!mp[to])continue;
			int sum = rp[chk + 1] - vp[i].first;
			//cout << root << " " << to << " " << sum + chk+1 << endl;
			memo[{root, to}] = { sum + chk,false };
		}
		c[root] = 1;
		int al = 1; bool va = true;
		rep(i, vp.size()) {
			if (i == chk)continue;
			if (vp[i].second == false) {
				al += vp[i].first;
				va = false;
				//chk = i;
				break;
			}
			else {
				al += vp[i].first;
				if (c[root] >= a[root]) {
					va = false; break;
				}
				c[root]++;
				al++;
			}
		}
		//cout << root << " " << ids[chk] << " " << al << endl;
		memo[{root, ids[chk]}] = { al,va };
	}
	rep(j, G[root].size()) {
		int to = G[root][j];
		if (!mp[to])continue;
		nex.clear();
		tonex(to, root);
		if (nex.size())que.push(nex);


	}
	rep(i, v.size())mp[v[i]] = false;
}


void solve() {
	cin >> n;
	rep(i, n) {
		cin >> a[i];
	}
	rep(i, n - 1) {
		int u, v; cin >> u >> v; u--; v--;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	vector<int> ori;
	rep(i, n) {
		sort(G[i].begin(), G[i].end());
		ori.push_back(i);
	}
	que.push(ori);
	while (!que.empty()) {
		vector<int> v = que.front(); que.pop();
		ans(v);
		//cout << "??" << endl;
	}
	rep(i, n) {
	    if(a[i]==0)out[i]=0;
		cout << out[i] << endl;
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	//stop
	return 0;
}
accuracy: 0.9285714285714286
time_ms: 1370
memory_kb: 66364
final_rank: 16

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
typedef pair<int, bool> sP;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef pair<ll, ll> LP;
typedef vector<ll> vec;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-5;
const ld pi = acos(-1.0);

int n;
const int mn = 300000;
int a[mn];
vector<int> G[mn];

int sz;
bool mp[mn];
int num[mn];
int g;
void dfs2(int id, int fr) {
	num[id] = 1;
	bool f = true;
	rep(j, G[id].size()) {
		int to = G[id][j];
		if (to == fr || !mp[to])continue;
		dfs2(to, id);
		num[id] += num[to];
		if (num[to] > sz / 2)f = false;
	}
	if (sz - num[id] > sz / 2)f = false;
	if (f)g = id;
}

map<P, sP> memo;
int out[mn];


int c[mn];
sP dfs(int id, int fr) {
	if (c[id] >= a[id]) {
		return { 0,false };
	}
	c[id]++;
	sP ret = { 1,true };
	rep(j, G[id].size()) {
		int to = G[id][j];
		if (to == fr)continue;
		if (!mp[to]) {
			sP p = memo[{to, id}];
			ret.first += p.first;
			ret.second = p.second;
			if (p.second == false) {
				return ret;
			}
		}
		else {
			sP p = dfs(to, id);
			ret.first += p.first;
			ret.second = p.second;
			if (p.second == false) {
				return ret;
			}
		}
		if (c[id] >= a[id])return { ret.first,false };
		c[id]++; ret.first++;
	}
	return ret;
}


vector<int> nex;
void tonex(int id, int fr) {
	nex.push_back(id);
	rep(j, G[id].size()) {
		int to = G[id][j];
		if (to == fr)continue;
		if (!mp[to])continue;
		tonex(to, id);
	}
}
queue<vector<int>> que;
void ans(vector<int> &v) {
	if (v.empty())return;
	sz = v.size();
	rep(i, v.size())mp[v[i]] = true;
	int root = v[0];
	g = root;
	dfs2(root, -1);
	root = g;
	rep(i, v.size())c[v[i]] = 0;
	bool exifalse = false;
	vector<sP> vp;
	vector<int> ids;
	rep(j, G[root].size()) {
		int to = G[root][j];
		sP p;
		if (mp[to]) {
			p = dfs(to, root);
			if (p.second == false && j<a[root]) {
				exifalse = true;
			}
			vp.push_back(p);
			ids.push_back(to);
		}
		else {
			p = memo[{to, root}];
			if (p.second == false && j<a[root]) {
				exifalse = true;
			}
			vp.push_back(p);
			ids.push_back(to);
		}
		//cout << root << " !!! " << to << " " << p.first << endl;
	}
	vector<int> rp(vp.size() + 1);
	rep(i, vp.size()) {
		rp[i + 1] = rp[i] + vp[i].first;
	}
	/*int chk = vp.size();
	if (!exifalse) {
	chk = min(chk, a[root]);
	}
	else {
	rep(i, vp.size()) {
	if (vp[i].second == false) {
	chk = i + 1; break;
	}
	}
	}*/
	/*Rep(i, chk, vp.size()) {
	int to = ids[i];
	if (mp[to]) {
	memo[{root, to}] = { rp[chk] + chk,false };
	}
	}*/
	out[root]++;
	if (!exifalse) {
		//cout << "Hello!" << endl;
		c[root] = 1;
		int chk = vp.size();
		rep(i, vp.size()) {
			//cout <<"hello "<< vp[i].first << endl;
			if (vp[i].second == false) {
				out[root] += vp[i].first;
				chk = i;
				break;
			}
			else {
				out[root] += vp[i].first;
				if (c[root] >= a[root]) {
					chk = i + 1;
					break;
				}
				c[root]++;
				out[root]++;
			}
		}
		//cout << "uoaaaa " << chk << endl;
		Rep(i, chk, vp.size()) {
			int cur = ids[i];
			if (mp[cur]) {
				//cout << root << " " << cur << " " << rp[chk] + chk << endl;
				memo[{root, cur}] = { rp[chk] + chk,false };
			}
		}
		if (chk == vp.size()) {
			rep(i, chk) {
				int to = ids[i];
				if (!mp[to])continue;
				int sum = rp[vp.size()] - vp[i].first;
				//cout << root << " " << to << " " << sum + chk << endl;
				memo[{root, to}] = { sum + chk,true };
			}
		}
		else {
			rep(i, chk) {
				int to = ids[i];
				if (!mp[to])continue;
				int sum = rp[chk + 1] - vp[i].first;
				//cout << root << " " << to << " " << sum + chk << endl;
				memo[{root, to}] = { sum + chk,false };
			}
		}
	}
	else {
		//cout << "aaaa" << endl;
		c[root] = 1;
		rep(i, vp.size()) {
			//cout << root << " ?? " << vp[i].first << ids[i]<<endl;
			//cout << vp[i].first << endl;
			if (vp[i].second == false) {
				out[root] += vp[i].first;
				//chk = i;
				break;
			}
			else {
				out[root] += vp[i].first;
				c[root]++;
				out[root]++;
			}
		}
		int chk = vp.size();
		rep(i, vp.size()) {
			if (vp[i].second == false) {
				chk = i; break;
			}
		}
		//cout << root << " " << ids[chk] << endl;
		Rep(i, chk + 1, vp.size()) {
			int cur = ids[i];
			if (!mp[cur])continue;
			//cout << root << " " << cur << " " << rp[chk+1] + chk+1 << endl;
			memo[{root, cur}] = { rp[chk + 1] + chk + 1,false };
		}
		rep(i, chk) {
			int to = ids[i];
			if (!mp[to])continue;
			int sum = rp[chk + 1] - vp[i].first;
			//cout << root << " " << to << " " << sum + chk+1 << endl;
			memo[{root, to}] = { sum + chk,false };
		}
		c[root] = 1;
		int al = 1; bool va = true;
		rep(i, vp.size()) {
			if (i == chk)continue;
			if (vp[i].second == false) {
				al += vp[i].first;
				va = false;
				//chk = i;
				break;
			}
			else {
				al += vp[i].first;
				if (c[root] >= a[root]) {
					va = false; break;
				}
				c[root]++;
				al++;
			}
		}
		//cout << root << " " << ids[chk] << " " << al << endl;
		memo[{root, ids[chk]}] = { al,va };
	}
	rep(j, G[root].size()) {
		int to = G[root][j];
		if (!mp[to])continue;
		nex.clear();
		tonex(to, root);
		if (nex.size())que.push(nex);


	}
	rep(i, v.size())mp[v[i]] = false;
}


void solve() {
	cin >> n;
	rep(i, n) {
		cin >> a[i];
	}
	rep(i, n - 1) {
		int u, v; cin >> u >> v; u--; v--;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	vector<int> ori;
	rep(i, n) {
		sort(G[i].begin(), G[i].end());
		ori.push_back(i);
	}
	que.push(ori);
	while (!que.empty()) {
		vector<int> v = que.front(); que.pop();
		ans(v);
		//cout << "??" << endl;
	}
	rep(i, n) {
		cout << out[i] << endl;
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	//stop
	return 0;
}
accuracy: 0.44047619047619047
time_ms: 1310
memory_kb: 61696
final_rank: 20

code_snippet: #include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<iomanip>
#include<math.h>
#include<complex>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<functional>
#include<assert.h>
#include<numeric>
using namespace std;
#define REP(i,m,n) for(int i=(int)(m) ; i < (int) (n) ; ++i )
#define rep(i,n) REP(i,0,n)
using ll = long long;
const int inf=1e9+7;
const ll longinf=1LL<<60 ;
const ll mod=1e9+7 ;


vector<int> v[303030];
vector<int> sum[303030],die[303030];
int a[303030];

pair<int,int> dfs(int x,int p){
    int m = v[x].size();
    die[x].resize(m+1), sum[x].resize(m+1);
    rep(i,m){
        if(v[x][i]==p)continue;
        auto ret = dfs(v[x][i],x);
        die[x][i+1] += ret.first;
        sum[x][i+1] += ret.second;
    }
    int ans = 0;
    int c = 0;
    rep(i,m){
        if(v[x][i]==p)continue;
        if(a[x]<=c)return {1,ans};
        ++ans;
        if(die[x][i+1])return {1,ans+sum[x][i+1]};
        ans += sum[x][i+1];
        ++c;
    }
    if(a[x]<=c)return {1,ans};
    ++ans;
    return {0,ans};
}

pair<int,int> ret[303030];
int ANS[303030];

void dfs2(int x,int p){
    int m = v[x].size();
    rep(i,m){
        if(v[x][i]==p)die[x][i+1]=ret[x].first,sum[x][i+1]=ret[x].second;
        die[x][i+1]+=die[x][i];
        sum[x][i+1]+=sum[x][i];
    }

    int ans = 0;
    bool ok=true;
    rep(j,m){
        if(a[x]<=j){
            ok=false;
            break;
        }
        ++ans;
        if(die[x][j+1]!=die[x][j]){
            ans+=sum[x][j+1]-sum[x][j];
            ok=false;
            break;
        }
        else ans += sum[x][j+1]-sum[x][j];
    }
    if(ok&&a[x]>=m+1)++ans;
    int ans2 = 0;
    ok=true;
    rep(j,m){
        if(a[x]<=j-1){
            ok=false;
            break;
        }
        ++ans2;
        if(die[x][j+1]!=die[x][j]){
            ans2+=sum[x][j+1]-sum[x][j];
            ok=false;
            break;
        }
        else ans2+=sum[x][j+1]-sum[x][j];
    }
    if(ok&&a[x]>=m)++ans2;
    else ok=false;
    rep(i,m){
        int to = v[x][i];
        if(v[x][i]==p)continue;
        if(i+1>a[x]){
            ret[to]={1,ans};
        }
        else {
            if(die[x][i]>=1){
                ret[to]={1,ans};
            }
            else if(die[x][i+1]==0){
                ret[to]={!ok,ans2-sum[x][i+1]+sum[x][i]-1};
            }
            else {
                int ans3 = 0;
                bool ok3=true;
                int c = 0;
                rep(j,m){
                    if(j==i)continue;
                    if(a[x]<=c){
                        ok3=false;
                        break;
                    }
                    ++ans3;
                    ++c;
                    if(die[x][j+1]!=die[x][j]){
                        ans3+=sum[x][j+1]-sum[x][j];
                        ok3=false;
                        break;
                    }
                    else ans3+=sum[x][j+1]-sum[x][j];
                }
                if(ok3&&a[x]>=m)++ans3;
                else ok3=false;
                ret[to]={!ok3,ans3};
            }
        }
    }
    ANS[x]=ans;
    for(auto to : v[x]){
        if(to==p)continue;
        dfs2(to,x);
    }
}
int main(){
    int n;
    cin>>n;
    rep(i,n)cin>>a[i];
    rep(i,n-1){
        int x,y;
        cin>>x>>y;
        --x;--y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    rep(i,n)sort(v[i].begin(),v[i].end());
    dfs(0,-1);
    dfs2(0,-1);
    rep(i,n)cout<<ANS[i]<<"\n";
    return 0;
}
accuracy: 1
time_ms: 490
memory_kb: 61888
final_rank: 2