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

#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (n); i++)
#define reps(i, x, n) for (int i = x; i < (n); i++)
#define rrep(i, n) for (int i = (n)-1; i >= 0; i--)
#define all(X) (X).begin(), (X).end()
#define X first
#define Y second
#define pb push_back
#define eb emplace_back

using namespace std;
typedef long long int ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

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;
}

template <class A, size_t N, class T> void Fill(A (&a)[N], const T &v) {
  fill((T *)a, (T *)(a + N), v);
}

template <class T> ostream &operator<<(ostream &os, const vector<T> &t) {
  os << "{";
  rep(i, t.size()) { os << t[i] << ","; }
  os << "}";
  return os;
}
template <class T, size_t n>
ostream &operator<<(ostream &os, const array<T, n> &t) {
  os << "{";
  rep(i, n) { os << t[i] << ","; }
  os << "}";
  return os;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &t) {
  return os << "(" << t.first << "," << t.second << ")";
}

const ll INF = 1e9 + 7;

const ll MOD = 1e9 + 7;

// n^m%MOD を求める。O( log(m) )
ll modpow(ll n, int m) {
  ll ret = 1;
  for (int i = 1; i <= m; i <<= 1, (n *= n) %= MOD) {
    if (m & i)
      (ret *= n) %= MOD;
  }
  return ret;
}

// 逆元を求める
ll modinv(ll n) { return modpow(n, MOD - 2); }

// 階乗を求める。O(1)  準備O( n*log(n) )
// fact[n]     : nの階乗
// fact.inv[n] : nの階乗の逆元
class FACTORIAL {
public:
  vector<ll> fact, inv;
  FACTORIAL(int MAX_NUM) : fact(MAX_NUM), inv(MAX_NUM) {
    fact[0] = inv[0] = 1;
    for (ll i = 1; i < MAX_NUM; i++) {
      fact[i] = (fact[i - 1] * i) % MOD;
      inv[i] = modinv(fact[i]);
    }
  }
  const ll &operator[](const int i) const { return fact[i]; }
} fact(200006); // nの最大値を指定

// 組み合わせ(Combinationを求める) O(1)
ll cmb(unsigned int n, unsigned int r) {
  if (n < r)
    return 0;
  return fact[n] * fact.inv[r] % MOD * fact.inv[n - r] % MOD;
}

vector<int> edge[200005];
map<int, pll> memo[200005];
pll all[200005];
pll solve(int n, int b) {
  if (memo[n].count(b))
    return memo[n][b];
  if (all[n].Y > 0) {
    if (b < 0) {
      auto ret = all[n];
      ret.Y += 1;
      return memo[n][b] = ret;
    }

    auto ret = solve(b, n);
    ll sum = all[n].X * modinv(ret.X) % MOD;
    sum = (sum * modinv(cmb(all[n].Y, ret.Y))) % MOD;
    ll cnt = all[n].Y - ret.Y;
    return memo[n][b] = pll(sum, cnt + 1);
  }
  ll sum = 1, cnt = 0;
  for (auto t : edge[n])
    if (t != b) {
      auto ret = solve(t, n);
      cnt += ret.Y;
      sum = (sum * cmb(cnt, ret.Y)) % MOD;
      sum = (sum * ret.X) % MOD;
    }
  if (b >= 0 && memo[b].count(n)) {
    all[n].Y = cnt + memo[b][n].Y;
    all[n].X = sum * memo[b][n].X % MOD;
    all[n].X = all[n].X * cmb(all[n].Y, memo[b][n].Y) % MOD;
  }
  cnt += 1;
  // cout << n << " " << b << ": " << pll(sum, cnt) << endl;
  return memo[n][b] = pll(sum, cnt);
}

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

  cin >> N;
  rep(i, N - 1) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    edge[a].push_back(b);
    edge[b].push_back(a);
  }

  vector<ll> ans;
  rep(i, N) ans.push_back(solve(i, -1).X);
  for (auto t : ans)
    printf("%lld\\n", t);

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (n); i++)
#define reps(i, x, n) for (int i = x; i < (n); i++)
#define rrep(i, n) for (int i = (n)-1; i >= 0; i--)
#define all(X) (X).begin(), (X).end()
#define X first
#define Y second
#define pb push_back
#define eb emplace_back

using namespace std;
typedef long long int ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

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;
}

template <class A, size_t N, class T> void Fill(A (&a)[N], const T &v) {
  fill((T *)a, (T *)(a + N), v);
}

template <class T> ostream &operator<<(ostream &os, const vector<T> &t) {
  os << "{";
  rep(i, t.size()) { os << t[i] << ","; }
  os << "}";
  return os;
}
template <class T, size_t n>
ostream &operator<<(ostream &os, const array<T, n> &t) {
  os << "{";
  rep(i, n) { os << t[i] << ","; }
  os << "}";
  return os;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &t) {
  return os << "(" << t.first << "," << t.second << ")";
}

const ll INF = 1e9 + 7;

const ll MOD = 1e9 + 7;

// n^m%MOD を求める。O( log(m) )
ll modpow(ll n, int m) {
  ll ret = 1;
  for (int i = 1; i <= m; i <<= 1, (n *= n) %= MOD) {
    if (m & i)
      (ret *= n) %= MOD;
  }
  return ret;
}

// 逆元を求める
ll modinv(ll n) { return modpow(n, MOD - 2); }

// 階乗を求める。O(1)  準備O( n*log(n) )
// fact[n]     : nの階乗
// fact.inv[n] : nの階乗の逆元
class FACTORIAL {
public:
  vector<ll> fact, inv;
  FACTORIAL(int MAX_NUM) : fact(MAX_NUM), inv(MAX_NUM) {
    fact[0] = inv[0] = 1;
    for (ll i = 1; i < MAX_NUM; i++) {
      fact[i] = (fact[i - 1] * i) % MOD;
      inv[i] = modinv(fact[i]);
    }
  }
  const ll &operator[](const int i) const { return fact[i]; }
} fact(200006); // nの最大値を指定

// 組み合わせ(Combinationを求める) O(1)
ll cmb(unsigned int n, unsigned int r) {
  if (n < r)
    return 0;
  return fact[n] * fact.inv[r] % MOD * fact.inv[n - r] % MOD;
}

vector<int> edge[200005];
map<int, pll> memo[200005];
pll solve(int n, int b) {
  if (memo[n].count(b))
    return memo[n][b];
  // vector<pll> v;
  ll sum = 1, cnt = 0;
  for (auto t : edge[n])
    if (t != b) {
      auto ret = solve(t, n);
      cnt += ret.Y;
      sum = (sum * cmb(cnt, ret.Y)) % MOD;
      sum = (sum * ret.X) % MOD;
    }
  // for(auto p: v) cnt += p.Y;
  // ll rest = cnt;
  // for(auto p: v){
  // 	sum = (sum * cmb(rest, p.Y)) % MOD;
  // 	sum = (sum * p.X) % MOD;
  // 	rest -= p.Y;
  // }
  cnt += 1;
  // cout << n << " " << b << ": " << pll(sum, cnt) << endl;
  return memo[n][b] = pll(sum, cnt);
}

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

  cin >> N;
  rep(i, N - 1) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    edge[a].push_back(b);
    edge[b].push_back(a);
  }

  vector<ll> ans;
  rep(i, N) ans.push_back(solve(i, -1).X);
  for (auto t : ans)
    printf("%lld\\n", t);

  return 0;
}