CSES - Shared codeLink to this code:
https://cses.fi/paste/883468c70b26846c5d50b1/
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define F first
#define S second
#define pb push_back
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef pair<ll,ll> T;
struct AllRoots {
int n;
vector<vi> adj;
vector<vector<T>> pre, suf;
const T unit = {0, 0};
AllRoots(int n) : n(n), adj(n), pre(n), suf(n) {}
// !!!
T merge(const T& v1, const T& v2) {
return {v1.F + v2.F, v1.S + v2.S};
}
T promote(const T& v1) {
return {v1.F + v1.S, v1.S + 1};
}
T get(int x, int i = 0){
return promote(merge(pre[x][i], suf[x][i+1]));
};
void addEdge(int u, int v){
adj[u].pb(v);
adj[v].pb(u);
}
T down(int x, int p = -1) {
for(auto& c : adj[x]) if(c == p) swap(c, adj[x][0]);
for(int i = adj[x].size()-1; i > -(p<0); --i)
suf[x][i] = merge(down(adj[x][i], x), suf[x][i+1]);
return get(x);
}
void up(int x, int p = -1) {
rep(i, p != -1, adj[x].size()) {
pre[x][i+1] = merge(pre[x][i], get(adj[x][i]));
pre[adj[x][i]][1] = get(x, i);
up(adj[x][i], x);
}
}
vector<T> calc(int root = 0) {
rep(i,0,n) {
pre[i].assign(adj[i].size() + 1, unit);
suf[i].assign(adj[i].size() + 1, unit);
}
down(root);
if(sz(adj[root]))
pre[root][1] = get(adj[root][0]);
up(root);
vector<T> res(n);
rep(i,0,n) res[i] = promote(pre[i].back());
return res;
}
};
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n; cin >> n;
AllRoots ar(n);
rep(i,0,n-1) {
int u,v; cin >> u >> v;
ar.addEdge(u-1, v-1);
}
auto res = ar.calc();
rep(i,0,n) cout << res[i].F << ' ';
cout<<endl;
}