Problem p02728 (C++)

Buggy submission (status: Runtime Error):
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
template <class T> using V = vector<T>;
#define fi first
#define se second
#define all(v) (v).begin(), (v).end()
const ll inf = (1e18);
// const ll mod=998244353;
const ll mod = 1000000007;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll c, ll d) { return c / gcd(c, d) * d; }
struct __INIT {
  __INIT() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
  }
} __init;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
struct mint {
  using ull = unsigned long long int;
  ull v;
  mint(ll vv = 0) { s(vv % mod + mod); }
  mint &s(ull vv) {
    v = vv < mod ? vv : vv - mod;
    return *this;
  }
  // オーバーロード
  mint operator-() const { return mint() - *this; } // 符号反転
  mint &operator+=(const mint &val) { return s(v + val.v); }
  mint &operator-=(const mint &val) { return s(v + mod - val.v); }
  mint &operator*=(const mint &val) {
    v = ull(v) * val.v % mod;
    return *this;
  }
  mint &operator/=(const mint &val) { return *this *= val.inv(); }
  mint operator+(const mint &val) { return mint(*this) += val; }
  mint operator-(const mint &val) { return mint(*this) -= val; }
  mint operator*(const mint &val) { return mint(*this) *= val; }
  mint operator/(const mint &val) { return mint(*this) /= val; }
  mint pow(ll n) const {
    mint res(1), x(*this);
    while (n) {
      if (n & 1)
        res *= x;
      x *= x;
      n >>= 1;
    }
    return res;
  }
  mint inv() const { return pow(mod - 2); }
  // 拡張ユークリッドの互除法
  /* mint inv()const{
      int x,y;
      int g=extgcd(v,mod,x,y);
      assert(g==1);
      if(x<0)x+=mod;
      return mint(x);
  }*/
  friend ostream &operator<<(ostream &os, const mint &val) {
    return os << val.v;
  } // 出力
  bool operator<(const mint &val) const { return v < val.v; }
  bool operator==(const mint &val) const { return v == val.v; }
  bool operator>(const mint &val) const { return v > val.v; }
};
const ll MAX = 2000010; // 設定
mint fac[MAX], finv[MAX], inv[MAX];
// テーブルを作る前処理
void init() {
  fac[0] = fac[1] = 1;
  for (int i = 1; i < MAX; i++)
    fac[i] = fac[i - 1] * i;
  finv[MAX - 1] = fac[MAX - 1].inv();
  for (int i = MAX - 2; i >= 0; i--)
    finv[i] = finv[i + 1] * (i + 1);
  for (int i = MAX - 2; i >= 1; i--)
    inv[i] = finv[i] + fac[i - 1];
}
// 階乗
mint factor(ll n, ll k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * finv[k];
}
// 二項係数計算
mint COM(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * finv[k] * finv[n - k];
}
V<V<int>> graph;
mint dp[200005];
int tree[20005];
void dfs1(int now, int par) {
  dp[now] = 1;
  tree[now]++;
  if (graph[now].size() == 1 && par != -1)
    return;
  for (int v : graph[now]) {
    if (par == v)
      continue;
    dfs1(v, now);
    tree[now] += tree[v];
  }
  dp[now] = fac[tree[now] - 1];
  for (int v : graph[now]) {
    if (par == v)
      continue;
    dp[now] /= fac[tree[v]];
    dp[now] *= dp[v];
  }
}
V<mint> ans;
void dfs2(int now, int par) {
  ans[now] = dp[now];
  if (par != -1) {
    int t = tree[par] - tree[now];
    ans[now] *=
        dp[par] / dp[now] * fac[tree[now]] / fac[tree[par] - 1] * fac[t - 1];
    ans[now] /= fac[tree[now] - 1];
    tree[now] = tree[par];
    ans[now] *= fac[tree[now] - 1] / fac[t];
    dp[now] = ans[now];
  }
  for (int v : graph[now]) {
    if (v == par)
      continue;
    dfs2(v, now);
  }
}
int main() {
  int n;
  cin >> n;
  init();
  graph.resize(n);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    graph[--a].emplace_back(--b);
    graph[b].emplace_back(a);
  }
  dfs1(0, -1);
  ans.resize(n);
  dfs2(0, -1);
  for (int i = 0; i < n; i++)
    cout << ans[i] << "\n";
}


Fixed submission:
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
template <class T> using V = vector<T>;
#define fi first
#define se second
#define all(v) (v).begin(), (v).end()
const ll inf = (1e18);
// const ll mod=998244353;
const ll mod = 1000000007;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll c, ll d) { return c / gcd(c, d) * d; }
struct __INIT {
  __INIT() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
  }
} __init;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
struct mint {
  using ull = unsigned long long int;
  ull v;
  mint(ll vv = 0) { s(vv % mod + mod); }
  mint &s(ull vv) {
    v = vv < mod ? vv : vv - mod;
    return *this;
  }
  // オーバーロード
  mint operator-() const { return mint() - *this; } // 符号反転
  mint &operator+=(const mint &val) { return s(v + val.v); }
  mint &operator-=(const mint &val) { return s(v + mod - val.v); }
  mint &operator*=(const mint &val) {
    v = ull(v) * val.v % mod;
    return *this;
  }
  mint &operator/=(const mint &val) { return *this *= val.inv(); }
  mint operator+(const mint &val) { return mint(*this) += val; }
  mint operator-(const mint &val) { return mint(*this) -= val; }
  mint operator*(const mint &val) { return mint(*this) *= val; }
  mint operator/(const mint &val) { return mint(*this) /= val; }
  mint pow(ll n) const {
    mint res(1), x(*this);
    while (n) {
      if (n & 1)
        res *= x;
      x *= x;
      n >>= 1;
    }
    return res;
  }
  mint inv() const { return pow(mod - 2); }
  // 拡張ユークリッドの互除法
  /* mint inv()const{
      int x,y;
      int g=extgcd(v,mod,x,y);
      assert(g==1);
      if(x<0)x+=mod;
      return mint(x);
  }*/
  friend ostream &operator<<(ostream &os, const mint &val) {
    return os << val.v;
  } // 出力
  bool operator<(const mint &val) const { return v < val.v; }
  bool operator==(const mint &val) const { return v == val.v; }
  bool operator>(const mint &val) const { return v > val.v; }
};
const ll MAX = 2000010; // 設定
mint fac[MAX], finv[MAX], inv[MAX];
// テーブルを作る前処理
void init() {
  fac[0] = fac[1] = 1;
  for (int i = 1; i < MAX; i++)
    fac[i] = fac[i - 1] * i;
  finv[MAX - 1] = fac[MAX - 1].inv();
  for (int i = MAX - 2; i >= 0; i--)
    finv[i] = finv[i + 1] * (i + 1);
  for (int i = MAX - 2; i >= 1; i--)
    inv[i] = finv[i] + fac[i - 1];
}
// 階乗
mint factor(ll n, ll k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * finv[k];
}
// 二項係数計算
mint COM(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * finv[k] * finv[n - k];
}
V<V<int>> graph;
mint dp[200005];
int tree[200005];
void dfs1(int now, int par) {
  dp[now] = 1;
  tree[now]++;
  if (graph[now].size() == 1 && par != -1)
    return;
  for (int v : graph[now]) {
    if (par == v)
      continue;
    dfs1(v, now);
    tree[now] += tree[v];
  }
  dp[now] = fac[tree[now] - 1];
  for (int v : graph[now]) {
    if (par == v)
      continue;
    dp[now] /= fac[tree[v]];
    dp[now] *= dp[v];
  }
}
V<mint> ans;
void dfs2(int now, int par) {
  ans[now] = dp[now];
  if (par != -1) {
    int t = tree[par] - tree[now];
    ans[now] *=
        dp[par] / dp[now] * fac[tree[now]] / fac[tree[par] - 1] * fac[t - 1];
    ans[now] /= fac[tree[now] - 1];
    tree[now] = tree[par];
    ans[now] *= fac[tree[now] - 1] / fac[t];
    dp[now] = ans[now];
  }
  for (int v : graph[now]) {
    if (v == par)
      continue;
    dfs2(v, now);
  }
}
int main() {
  int n;
  cin >> n;
  init();
  graph.resize(n);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    graph[--a].emplace_back(--b);
    graph[b].emplace_back(a);
  }
  dfs1(0, -1);
  ans.resize(n);
  dfs2(0, -1);
  for (int i = 0; i < n; i++)
    cout << ans[i] << "\n";
}