Language: C++

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
 
const int M = 1e9 + 7;
const int N = 2e5 + 10; 
long long dp[N] = {0}, ans[N] = {0};
long long fact_ret[N] = {0};
int tree_size[N] = {0};
int visit[N] = {0};
struct edge{
    int v, next;
} edges[N<<1];
int e_cnt = 0;
int head[N];

void add(int u, int v) {
    edges[e_cnt].v = v; edges[e_cnt].next = head[u]; head[u] = e_cnt++;  
}

void cal_fact() {
    fact_ret[0] = 1;
    for (int i = 1; i < N; ++i) 
        fact_ret[i] = fact_ret[i-1] * i % M;
}

int cal_size(int root) {
    visit[root] = 1;
    if (tree_size[root] != 0) return tree_size[root];
    tree_size[root] = 1;
    for (int e = head[root]; e != -1; e = edges[e].next) {
        if (visit[edges[e].v]) continue;
        tree_size[root] += cal_size(edges[e].v);
    }
    return tree_size[root];
}

int cal_dp(int root) {
    // cout << "dp " << root << endl;
    visit[root] = 1;
    if (dp[root] != 0) return dp[root];
    dp[root] = fact_ret[tree_size[root] - 1];
    if (tree_size[root] == 1) return dp[root]; 
    for (int e = head[root]; e != -1; e = edges[e].next) {
        int v = edges[e].v;
        // cout << "v " << v << endl;
        if (visit[v]) continue;
        dp[root] = dp[root] / fact_ret[tree_size[v]] % M;
        dp[root] = (dp[root] * cal_dp(v)) % M ;
    } 
    return dp[root];
}

void root_transfer(int root) {
    visit[root] = 1;
    for (int e = head[root]; e != -1; e = edges[e].next) {
        int u = root, v = edges[e].v;
        if (visit[v]) continue;
        long long new_size_v = tree_size[u];
        long long new_size_u = tree_size[u] - tree_size[v];
        assert(("No zero", dp[v] != 0));
        long long new_dp_u = dp[u] * fact_ret[tree_size[v]]* fact_ret[new_size_u - 1]  / dp[v] / fact_ret[tree_size[u] - 1] % M;
        long long new_dp_v = dp[v]  * new_dp_u * fact_ret[new_size_v - 1]/ fact_ret[new_size_u] / fact_ret[tree_size[v] - 1] % M;
        long long old_size_v = tree_size[v], old_size_u = tree_size[u], old_dp_u = dp[u], old_dp_v = dp[v];

        ans[v] = new_dp_v;
        dp[u] = new_dp_u; dp[v] = new_dp_v;
        tree_size[u] = new_size_u; tree_size[v] = new_size_v;
        // cout << root << ' ' << v << ' ' << new_dp_u << ' ' << new_dp_v << endl;
        root_transfer(v);
        dp[u] = old_dp_u; dp[v] = old_dp_v;
        tree_size[u] = old_size_u; tree_size[v] = old_size_u;
    }
}


int main()
{
    memset(head, -1, sizeof(head));
    memset(dp, 0, sizeof(dp));
    memset(fact_ret, -1, sizeof(fact_ret));
    int n;
    cin >> n;
    for (int i = 0; i < n-1; ++i) {
        int a, b;
        cin >> a >> b;
        add(a, b); add(b, a);
    }

    cal_fact();

    memset(visit, 0, sizeof(visit));
    memset(tree_size, 0, sizeof(tree_size));
    cal_size(1);
    memset(dp, 0, sizeof(dp));
    memset(visit, 0, sizeof(visit));
    cal_dp(1);

    ans[1] = dp[1];
    memset(visit, 0, sizeof(visit));
    root_transfer(1);

    for (int i = 1; i <= n; ++i) 
        cout << ans[i] << endl;
    
    return 0;
}

Compiler output:
a.cc: In function 'void root_transfer(int)':
a.cc:62:9: error: 'assert' was not declared in this scope
   62 |         assert(("No zero", dp[v] != 0));
      |         ^~~~~~
a.cc:4:1: note: 'assert' is defined in header '<cassert>'; this is probably fixable by adding '#include <cassert>'
    3 | #include <cstring>
  +++ |+#include <cassert>
    4 | using namespace std;