Problem p02728 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
#define all(x) (x).begin(), (x).end()
#define fsp(x) fixed << setprecision(x)
const ll p = 1e9 + 7;
// const ll p = 998244353;
const ll inf = LLONG_MAX;
const long double pi = acos(-1);
void Yes() { cout << "Yes" << endl; }
void No() { cout << "No" << endl; }
void YES() { cout << "YES" << endl; }
void NO() { cout << "NO" << endl; }

vll factorial(2e5, 1);
void make_table() {
  for (ll i = 2; i <= 2e5; i++) {
    factorial[i] = factorial[i - 1] * i % p;
  }
}

// モジュラ逆数
long long modinv(long long n, long long p) {
  long long a = p, u = 1, v = 0;
  while (a) {
    long long t = n / a;
    n -= t * a;
    std::swap(n, a);
    u -= t * v;
    std::swap(u, v);
  }
  u %= p;
  if (u < 0)
    u += p;
  return u;
}

struct rerooting {
  ll n;           // 頂点数
  vector<vll> nx; // 隣接リスト
  unordered_map<ll, unordered_map<ll, ll>>
      dp1; // 有向辺 i -> j で表される部分木における場合の数
  unordered_map<ll, unordered_map<ll, ll>>
      dp2; // 有向辺 i -> j で表される部分木の頂点数
  vll dp3; // 頂点 i を根としたときの求める場合の数

  // コンストラクタ
  rerooting(ll m, vector<vll> &v) {
    n = m;
    nx = v;
    dp3.resize(n, 0);
  }

  void calc_sub(ll a, ll b) {
    if (dp1[a][b] > 0 && dp2[a][b] > 0)
      return;
    if (nx[b].size() == 1) {
      dp1[a][b] = 1;
      dp2[a][b] = 1;
      return;
    }
    if (dp3[b] > 0) {
      dp2[a][b] = n - dp2[b][a];
      ll x = dp3[b];
      x *= modinv(dp1[b][a], p);
      x %= p;
      x *= factorial[dp2[b][a]];
      x %= p;
      x *= modinv(factorial[n - 1], p) * factorial[n - 1 - dp2[b][a]] % p;
      x %= p;
      dp1[a][b] = x;
    } else {
      ll x = 1, sum = 0;
      for (ll i = 0; i < nx[b].size(); i++) {
        if (nx[b][i] == a)
          continue;
        calc_sub(b, nx[b][i]);
        x *= dp1[b][nx[b][i]];
        x %= p;
        x *= modinv(factorial[dp2[b][nx[b][i]]], p);
        x %= p;
        sum += dp2[b][nx[b][i]];
      }
      x *= factorial[sum];
      x %= p;
      dp1[a][b] = x;
      dp2[a][b] = sum + 1;
    }
  }

  void calc(ll a) {
    ll ret = factorial[n - 1], sum = 0;
    for (ll i = 0; i < nx[a].size(); i++) {
      calc_sub(a, nx[a][i]);
      ret *= dp1[a][nx[a][i]];
      ret %= p;
      ret *= modinv(factorial[dp2[a][nx[a][i]]], p);
      ret %= p;
    }
    dp3[a] = ret;
    return;
  }

  void bfs() {
    queue<ll> task;
    vector<bool> seen(n, false);
    task.push(0);
    seen[0] = true;
    while (task.size()) {
      calc(task.front());
      for (ll i = 0; i < nx[task.front()].size(); i++) {
        if (!seen[nx[task.front()][i]]) {
          task.push(nx[task.front()][i]);
          seen[nx[task.front()][i]] = true;
        }
      }
      task.pop();
    }
  }
};

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

  ll n;
  cin >> n;
  vector<vll> nx(n, vll(0));
  for (ll i = 0; i < n - 1; i++) {
    ll a, b;
    cin >> a >> b;
    nx[a - 1].push_back(b - 1);
    nx[b - 1].push_back(a - 1);
  }

  make_table();

  rerooting rr(n, nx);
  rr.bfs();
  for (ll i = 0; i < n; i++) {
    cout << rr.dp3[i] << endl;
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
#define all(x) (x).begin(), (x).end()
#define fsp(x) fixed << setprecision(x)
const ll p = 1e9 + 7;
// const ll p = 998244353;
const ll inf = LLONG_MAX;
const long double pi = acos(-1);
void Yes() { cout << "Yes" << endl; }
void No() { cout << "No" << endl; }
void YES() { cout << "YES" << endl; }
void NO() { cout << "NO" << endl; }

vll factorial(2e5, 1);
void make_table() {
  for (ll i = 2; i <= 2e5; i++) {
    factorial[i] = factorial[i - 1] * i % p;
  }
}

// モジュラ逆数
long long modinv(long long n, long long p) {
  long long a = p, u = 1, v = 0;
  while (a) {
    long long t = n / a;
    n -= t * a;
    std::swap(n, a);
    u -= t * v;
    std::swap(u, v);
  }
  u %= p;
  if (u < 0)
    u += p;
  return u;
}

template <typename T> struct rerooting {
  ll n;         // 頂点数
  vector<T> nx; // 隣接リスト
  unordered_map<ll, unordered_map<ll, ll>>
      dp1; // 有向辺 i -> j で表される部分木における場合の数
  unordered_map<ll, unordered_map<ll, ll>>
      dp2; // 有向辺 i -> j で表される部分木の頂点数
  vll dp3; // 頂点 i を根としたときの求める場合の数

  // コンストラクタ
  rerooting(ll m, vector<T> &v) {
    n = m;
    nx = v;
    dp3.resize(n, 0);
  }

  void calc_sub(ll a, ll b) {
    if (dp1[a][b] > 0 && dp2[a][b] > 0)
      return;
    if (nx[b].size() == 1) {
      dp1[a][b] = 1;
      dp2[a][b] = 1;
      return;
    }
    if (dp3[b] > 0) {
      dp2[a][b] = n - dp2[b][a];
      ll x = dp3[b];
      x *= modinv(dp1[b][a], p);
      x %= p;
      x *= factorial[dp2[b][a]];
      x %= p;
      x *= modinv(factorial[n - 1], p) * factorial[n - 1 - dp2[b][a]] % p;
      x %= p;
      dp1[a][b] = x;
    } else {
      ll x = 1, sum = 0;
      for (ll i = 0; i < nx[b].size(); i++) {
        if (nx[b][i] == a)
          continue;
        calc_sub(b, nx[b][i]);
        x *= dp1[b][nx[b][i]];
        x %= p;
        x *= modinv(factorial[dp2[b][nx[b][i]]], p);
        x %= p;
        sum += dp2[b][nx[b][i]];
      }
      x *= factorial[sum];
      x %= p;
      dp1[a][b] = x;
      dp2[a][b] = sum + 1;
    }
  }

  ll calc(ll a) {
    if (dp3[a] > 0)
      return dp3[a];
    ll ret = factorial[n - 1], sum = 0;
    for (ll i = 0; i < nx[a].size(); i++) {
      calc_sub(a, nx[a][i]);
      ret *= dp1[a][nx[a][i]];
      ret %= p;
      ret *= modinv(factorial[dp2[a][nx[a][i]]], p);
      ret %= p;
    }
    return dp3[a] = ret;
  }
};

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

  ll n;
  cin >> n;
  vector<vll> nx(n, vll(0));
  for (ll i = 0; i < n - 1; i++) {
    ll a, b;
    cin >> a >> b;
    nx[a - 1].push_back(b - 1);
    nx[b - 1].push_back(a - 1);
  }

  make_table();

  rerooting<vll> rr(n, nx);
  for (ll i = 0; i < n; i++) {
    cout << rr.calc(i) << endl;
  }
}