Problem p02728 (C++)

Buggy submission (status: Runtime Error):
#include <iostream>
#include <vector>

using namespace std;

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

#define MX 200005
#define MOD 1'000'000'007
#define invmod(x) bigmod(x, MOD - 2)
#define br '\n'

ll bigmod(ll base, ll pw) {
  ll ret = 1;
  while (pw) {
    if (pw & 1)
      ret = ret * base % MOD;
    base = base * base % MOD;
    pw >>= 1;
  }
  return ret;
}

int n;
ll fact[MX], inv[MX];

void calc() {
  fact[0] = 1;
  inv[0] = invmod(1);
  for (int i = 1; i < MX; i++) {
    fact[i] = i * fact[i - 1] % MOD;
    inv[i] = invmod(fact[i]);
  }
}

void treedp(int u, int p, const vector<vi> &adj, vi &sz, vector<ll> &dp) {
  dp[u] = 1;
  sz[u] = 1;
  for (auto v : adj[u]) {
    if (v != p) {
      treedp(v, u, adj, sz, dp);
      dp[u] = dp[u] * (dp[v] * inv[sz[v]] % MOD) % MOD;
      sz[u] += sz[v];
    }
  }
  dp[u] = dp[u] * fact[sz[u] - 1] % MOD;
}

void reroot(int u, int p, const vector<vi> &adj, vi &sz, vector<ll> &dp) {
  dp[u] = dp[p] * invmod(dp[u] * inv[sz[u]] % MOD) % MOD;
  dp[u] = dp[u] * invmod(n - sz[u]) % MOD;
  for (auto v : adj[u]) {
    if (v != p) {
      dp[u] = dp[u] * (dp[v] * inv[sz[v]] % MOD) % MOD;
    }
  }
  for (auto v : adj[u]) {
    if (v != p) {
      reroot(v, u, adj, sz, dp);
    }
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
#endif

  calc();

  while (cin >> n) {
    vector<vi> adj(n);
    vi sz(n);
    vector<ll> dp(n);

    int u, v;
    for (int i = 1; i < n; i++) {
      cin >> u >> v;
      u--;
      v--;
      adj[u].push_back(v);
      adj[v].push_back(u);
    }

    treedp(0, -1, adj, sz, dp);
    for (auto u : adj[0])
      reroot(u, 0, adj, sz, dp);
    for (auto x : dp)
      cout << x << br;
  }

  return 0;
}


Fixed submission:
#include <iostream>
#include <vector>

using namespace std;

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

#define MX 200005
#define MOD 1'000'000'007
#define invmod(x) bigmod(x, MOD - 2)
#define br '\n'

ll bigmod(ll base, ll pw) {
  ll ret = 1;
  while (pw) {
    if (pw & 1)
      ret = ret * base % MOD;
    base = base * base % MOD;
    pw >>= 1;
  }
  return ret;
}

int n;
ll fact[MX], inv[MX];

void calc() {
  fact[0] = 1;
  inv[0] = invmod(1);
  for (int i = 1; i < MX; i++) {
    fact[i] = i * fact[i - 1] % MOD;
    inv[i] = invmod(fact[i]);
  }
}

void treedp(int u, int p, const vector<vi> &adj, vi &sz, vector<ll> &dp) {
  dp[u] = 1;
  sz[u] = 1;
  for (auto v : adj[u]) {
    if (v != p) {
      treedp(v, u, adj, sz, dp);
      dp[u] = dp[u] * (dp[v] * inv[sz[v]] % MOD) % MOD;
      sz[u] += sz[v];
    }
  }
  dp[u] = dp[u] * fact[sz[u] - 1] % MOD;
}

void reroot(int u, int p, const vector<vi> &adj, vi &sz, vector<ll> &dp) {
  dp[u] = dp[p] * invmod(dp[u] * inv[sz[u]] % MOD) % MOD;
  dp[u] = dp[u] * invmod(n - sz[u]) % MOD;
  for (auto v : adj[u]) {
    if (v != p) {
      dp[u] = dp[u] * (dp[v] * inv[sz[v]] % MOD) % MOD;
    }
  }
  for (auto v : adj[u]) {
    if (v != p) {
      reroot(v, u, adj, sz, dp);
    }
  }
}

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

  calc();

  while (cin >> n) {
    vector<vi> adj(n);
    vi sz(n);
    vector<ll> dp(n);

    int u, v;
    for (int i = 1; i < n; i++) {
      cin >> u >> v;
      u--;
      v--;
      adj[u].push_back(v);
      adj[v].push_back(u);
    }

    treedp(0, -1, adj, sz, dp);
    for (auto u : adj[0])
      reroot(u, 0, adj, sz, dp);
    for (auto x : dp)
      cout << x << br;
  }

  return 0;
}