Problem p02728 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fbo find_by_order
#define ook order_of_key

typedef long long ll;
typedef pair<ll, ll> ii;
typedef vector<int> vi;
typedef long double ld;
typedef tree<ll, null_type, less<ll>, rb_tree_tag,
             tree_order_statistics_node_update>
    pbds;

vector<int> fact;
vector<int> ifact;
vector<int> inv;
vector<int> pow2;
const int MOD = (1e9 + 7);
int add(int a, int b) {
  a += b;
  while (a >= MOD)
    a -= MOD;
  return a;
}
void radd(int &a, int b) { a = add(a, b); }
int mult(int a, int b) { return (a * 1LL * b) % MOD; }
void rmult(int &a, int b) { a = mult(a, b); }
int modpow(int a, int b) {
  int r = 1;
  while (b) {
    if (b & 1)
      r = mult(r, a);
    a = mult(a, a);
    b >>= 1;
  }
  return r;
}
int choose(int a, int b) {
  if (a < b)
    return 0;
  if (b == 0)
    return 1;
  if (a == b)
    return 1;
  return mult(fact[a], mult(ifact[b], ifact[a - b]));
}
int inverse(int a) { return modpow(a, MOD - 2); }
void init(int _n) {
  fact.clear();
  ifact.clear();
  inv.clear();
  pow2.clear();
  fact.resize(_n + 1);
  ifact.resize(_n + 1);
  inv.resize(_n + 1);
  pow2.resize(_n + 1);
  pow2[0] = 1;
  ifact[0] = 1;
  fact[0] = 1;
  for (int i = 1; i <= _n; i++) {
    pow2[i] = add(pow2[i - 1], pow2[i - 1]);
    fact[i] = mult(fact[i - 1], i);
    // ifact[i]=mult(ifact[i-1],inv[i]);
  }
  ifact[_n] = inverse(fact[_n]);
  for (int i = _n - 1; i >= 1; i--) {
    ifact[i] = mult(ifact[i + 1], i + 1);
  }
  for (int i = 1; i <= _n; i++) {
    inv[i] = mult(fact[i - 1], ifact[i]);
  }
}

vi adj[222222];
int sub[222222];

void dfs(int u, int p = -1) {
  sub[u] = 1;
  for (int v : adj[u]) {
    if (v == p)
      continue;
    dfs(v, u);
    sub[u] += sub[v];
  }
}

int dp[222222];
int dpup[222222];
int ans[222222];

void dfs1(int u, int p) {
  int prod = 1;
  for (int v : adj[u]) {
    if (v == p)
      continue;
    dfs1(v, u);
    prod = mult(prod, dp[v]);
    prod = mult(prod, ifact[sub[v]]);
  }
  prod = mult(prod, fact[sub[u] - 1]);
  dp[u] = prod;
}
int par[333333];
int n;
void dfs2(int u, int p) {
  par[u] = p;
  for (int v : adj[u]) {
    if (v == p)
      continue;
    // compute dpup[v]
    int totsiz = n - sub[v];
    dpup[v] = mult(dp[u], ifact[sub[u] - 1]);
    dpup[v] = mult(dpup[v], inverse(dp[v]));
    dpup[v] = mult(dpup[v], fact[sub[v]]);
    if (u != 0) {
      dpup[v] = mult(dpup[v], dpup[u]);
      dpup[v] = mult(dpup[v], ifact[n - sub[u]]);
    }
    dpup[v] = mult(dpup[v], fact[totsiz - 1]);
    dfs2(v, u);
  }
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  init(333333);
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    adj[u].pb(v);
    adj[v].pb(u);
  }
  dfs(0, -1);
  dfs1(0, -1);
  dfs2(0, -1);
  for (int i = 0; i < n; i++) {
    int ans = fact[n - 1];
    for (int v : adj[i]) {
      if (v != par[i]) {
        ans = mult(ans, dp[v]);
        ans = mult(ans, ifact[sub[v]]);
      } else {
        ans = mult(ans, dpup[i]);
        ans = mult(ans, ifact[n - sub[i]]);
      }
    }
    cout << ans << '\\n';
  }
}


Error: WA

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const int MAX = 100001;
vector<ll> adj[100001];
ll dp1[MAX], dp2[MAX];
ll vis[MAX], parent[MAX];
ll children[MAX];
ll counts[MAX];
ll P = 1000000007;
vector<ll> levels[MAX];
ll gcdExtended(ll a, ll b, ll *x, ll *y);
ll modInverse(ll a, ll m) {
  ll x, y;
  ll g = gcdExtended(a, m, &x, &y);
  ll res = (x % m + m) % m;
  return res;
}
ll gcdExtended(ll a, ll b, ll *x, ll *y) {
  if (a == 0) {
    *x = 0, *y = 1;
    return b;
  }
  ll x1, y1;
  ll gcd = gcdExtended(b % a, a, &x1, &y1);
  *x = y1 - (b / a) * x1;
  *y = x1;

  return gcd;
}
ll fact[MAX];
void dfs(ll src, ll p, ll level) {
  vis[src] = 1;
  counts[src] = 1;
  dp1[src] = 1;
  levels[level].push_back(src);
  for (ll i = 0; i < adj[src].size(); i++) {
    ll v = adj[src][i];
    if (!vis[v]) {
      if (v == p) {
        continue;
      }
      dfs(v, src, level + 1);
      counts[src] += counts[v];
      children[src] = v;
      parent[v] = src;
    }
  }
}
int main() {
  ll t, i, j, k, l, m, n, o, p, q, r, s, tt = 0;
  memset(vis, 0, sizeof(vis));
  memset(parent, 0, sizeof(vis));
  memset(children, 0, sizeof(vis));
  memset(counts, 0, sizeof(vis));
  memset(dp1, 0, sizeof(vis));
  memset(dp2, 0, sizeof(vis));

  cin >> n;
  fact[0] = 1;
  for (i = 0; i < n - 1; i++) {
    levels[i + 1].clear();
    fact[i + 1] = (fact[i] * (i + 1)) % P;
    cin >> j >> k;
    adj[j].push_back(k);
  }
  dfs(1, 0, 1);
  for (i = 1; i <= n; i++) {
    // cout<<counts[i]<<" "<<parent[i]<<endl;;
  }
  // moving from bottom to top and computing
  // the values
  for (i = n; i >= 1; i--) {
    for (j = 0; j < levels[i].size(); j++) {
      ll node = levels[i][j];
      dp1[node] = (dp1[node] * fact[counts[node] - 1]) % P;
      for (l = 0; l < adj[node].size(); l++) {
        if (adj[node][l] != parent[node]) {
          dp1[node] = (dp1[adj[node][l]] * dp1[node]) % P;
          ll fact1 = fact[counts[adj[node][l]]];
          dp1[node] = (dp1[node] * modInverse(fact1, P)) % P;
        }
      }
    }
  }
  ll ans[MAX];
  ll counts1[MAX];
  ans[1] = dp1[1];
  dp2[1] = dp1[1];
  for (i = 2; i <= n; i++) {
    // calculating at this level first!
    for (j = 0; j < levels[i].size(); j++) {
      ll node = levels[i][j];
      // now making node as root and applying reroooting technique in O(1) time
      ll pp = parent[node];
      ll old_count_p, old_count_n, new_count_p, new_count_n;
      old_count_p = n;
      new_count_n = n;
      old_count_n = counts[node];
      new_count_p = n - old_count_n;

      ll dp1_p, dp1_n, dp2_p, dp2_n;
      dp1_p = dp2[pp];
      dp1_n = dp1[node];
      dp2_p = (dp1_p * modInverse(fact[old_count_p - 1], P)) % P;
      dp2_p = (dp2_p * modInverse(dp1_n, P)) % P;
      dp2_p = (dp2_p * fact[new_count_p - 1]) % P;
      dp2_p = (dp2_p * fact[old_count_n]) % P;

      // still I need to calculate dp_2_n but how
      dp2_n = dp1[node];
      dp2_n = (dp2_n * modInverse(fact[old_count_n - 1], P)) % P;
      dp2_n = (dp2_n * fact[new_count_n - 1]) % P;
      dp2_n = (dp2_n * dp2_p) % P;
      dp2_n = (dp2_n * modInverse(fact[new_count_p], P)) % P;

      dp2[node] = dp2_n;
      ans[node] = dp2_n;
      // upsolving codejam and kickstart questions is a big deal.
    }
  }
  for (i = 1; i <= n; i++) {
    cout << ans[i] << "\\n";
  }
  cout << endl;
  return 0;
}