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

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> ii;
typedef tuple<ll, ll, ll> iii;
typedef vector<ll> vi;
typedef vector<ii> vii;
typedef vector<iii> viii;
typedef vector<vi> vvi;
typedef vector<vii> vvii;
#define REP(i, n) for (ll i = 0; i < n; ++i)
#define REPR(i, n) for (ll i = n - 1; i >= 0; --i)
#define FOR(i, m, n) for (ll i = m; i < n; ++i)
#define FORR(i, m, n) for (ll i = n - 1; i >= m; --i)
#define FORE(x, xs) for (const auto &x : xs)
#define ALL(v) v.begin(), v.end()
#define CHMIN(x, y) x = min(x, y)
#define CHMAX(x, y) x = max(x, y)

template <int mod> struct ModInt {
  int64_t x;
  ModInt() : x(0) {}
  ModInt(int64_t y) : x(y >= 0 ? y % mod : (y % mod + mod) % mod) {}

  ModInt &operator+=(const ModInt &a) {
    if ((x += a.x) >= mod)
      x -= mod;
    return *this;
  }

  ModInt &operator-=(const ModInt &a) {
    if ((x += mod - a.x) >= mod)
      x -= mod;
    return *this;
  }

  ModInt &operator*=(const ModInt &a) {
    x = 1LL * x * a.x % mod;
    return *this;
  }

  ModInt &operator/=(const ModInt &a) {
    *this *= a.inverse();
    return *this;
  }

  ModInt operator-() const { return ModInt(-x); }

  ModInt operator+(const ModInt a) const { return ModInt(*this) += a; }

  ModInt operator-(const ModInt a) const { return ModInt(*this) -= a; }

  ModInt operator*(const ModInt a) const { return ModInt(*this) *= a; }

  ModInt operator/(const ModInt a) const { return ModInt(*this) /= a; }

  bool operator==(const ModInt a) const { return x == a.x; }

  bool operator!=(const ModInt a) const { return x != a.x; }

  ModInt pow(int64_t k) const {
    ModInt ret(1), mul(x);
    while (k > 0) {
      if (k & 1)
        ret *= mul;
      mul *= mul;
      k >>= 1;
    }
    return ret;
  }

  ModInt inverse() const { return pow(mod - 2); }

  friend ostream &operator<<(ostream &os, const ModInt &p) { return os << p.x; }

  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt<mod>(t);
    return (is);
  }
};

const int MOD = 1e9 + 7;
using modint = ModInt<MOD>;

const int MAX = 2e5 + 10;

modint fac[MAX];
modint finv[MAX];
modint inv_[MAX];

void init() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv_[1] = 1;
  FOR(i, 2, MAX) {
    fac[i] = fac[i - 1] * modint(i);
    inv_[i] = -inv_[MOD % i] * modint(MOD / i);
    finv[i] = finv[i - 1] * inv_[i];
  }
}

modint nCk(int n, int k) {
  if (n < k || k < 0 || n < 0)
    return 0;
  return fac[n] * finv[k] * finv[n - k];
}

int N;
vi adj[MAX];

vi cnt[MAX], ptn[MAX];
vector<bool> chk[MAX];

struct DP {
  modint dp;
  int t;

  DP(modint dp = 1, int t = 0) : dp(dp), t(t) {}

  DP operator+(const DP &a) const {
    DP res(*this);
    res.dp *= a.dp;
    res.dp *= nCk(res.t + a.t, res.t);
    res.t += a.t;
    return res;
  }

  DP operator-(const DP &a) const {
    DP res(*this);
    res.t -= a.t;
    res.dp /= a.dp;
    res.dp /= nCk(res.t + a.t, res.t);
    return res;
  }

  DP addRoot() const {
    DP res(*this);
    res.t++;
    return res;
  }
};

DP dp[MAX];

void dnf(int node, int parent = -1) {
  FORE(a, adj[node]) {
    if (a == parent)
      continue;
    dnf(a, node);
    dp[node] = dp[node] + dp[a].addRoot();
  }
}

DP dnf2(int node, int parent = -1) {
  FORE(a, adj[node]) {
    if (a == parent)
      continue;
    DP diff = dp[node] - dp[a].addRoot();
    dp[a] = dp[a] + diff.addRoot();
    dnf2(a, node);
  }
}

void solve() {
  init();
  dnf(0);
  dnf2(0);
  REP(i, N) cout << dp[i].dp << endl;
}

int main() {
  cin >> N;
  REP(i, N - 1) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  solve();
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> ii;
typedef tuple<ll, ll, ll> iii;
typedef vector<ll> vi;
typedef vector<ii> vii;
typedef vector<iii> viii;
typedef vector<vi> vvi;
typedef vector<vii> vvii;
#define REP(i, n) for (ll i = 0; i < n; ++i)
#define REPR(i, n) for (ll i = n - 1; i >= 0; --i)
#define FOR(i, m, n) for (ll i = m; i < n; ++i)
#define FORR(i, m, n) for (ll i = n - 1; i >= m; --i)
#define FORE(x, xs) for (const auto &x : xs)
#define ALL(v) v.begin(), v.end()
#define CHMIN(x, y) x = min(x, y)
#define CHMAX(x, y) x = max(x, y)

template <int mod> struct ModInt {
  int64_t x;
  ModInt() : x(0) {}
  ModInt(int64_t y) : x(y >= 0 ? y % mod : (y % mod + mod) % mod) {}

  ModInt &operator+=(const ModInt &a) {
    if ((x += a.x) >= mod)
      x -= mod;
    return *this;
  }

  ModInt &operator-=(const ModInt &a) {
    if ((x += mod - a.x) >= mod)
      x -= mod;
    return *this;
  }

  ModInt &operator*=(const ModInt &a) {
    x = 1LL * x * a.x % mod;
    return *this;
  }

  ModInt &operator/=(const ModInt &a) {
    *this *= a.inverse();
    return *this;
  }

  ModInt operator-() const { return ModInt(-x); }

  ModInt operator+(const ModInt a) const { return ModInt(*this) += a; }

  ModInt operator-(const ModInt a) const { return ModInt(*this) -= a; }

  ModInt operator*(const ModInt a) const { return ModInt(*this) *= a; }

  ModInt operator/(const ModInt a) const { return ModInt(*this) /= a; }

  bool operator==(const ModInt a) const { return x == a.x; }

  bool operator!=(const ModInt a) const { return x != a.x; }

  ModInt pow(int64_t k) const {
    ModInt ret(1), mul(x);
    while (k > 0) {
      if (k & 1)
        ret *= mul;
      mul *= mul;
      k >>= 1;
    }
    return ret;
  }

  ModInt inverse() const { return pow(mod - 2); }

  friend ostream &operator<<(ostream &os, const ModInt &p) { return os << p.x; }

  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt<mod>(t);
    return (is);
  }
};

const int MOD = 1e9 + 7;
using modint = ModInt<MOD>;

const int MAX = 2e5 + 10;

modint fac[MAX << 2];
modint finv[MAX << 2];
modint inv_[MAX << 2];

void init() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv_[1] = 1;
  FOR(i, 2, MAX << 2) {
    fac[i] = fac[i - 1] * modint(i);
    inv_[i] = -inv_[MOD % i] * modint(MOD / i);
    finv[i] = finv[i - 1] * inv_[i];
  }
}

int N;
vi adj[MAX];

vi cnt[MAX], ptn[MAX];
vector<bool> chk[MAX];
map<ii, ii> memo;

ii dnf(int node, int parent) {
  int n = 0;
  modint p(1);
  REP(i, adj[node].size()) {
    if (adj[node][i] == parent)
      continue;
    if (!chk[node][i]) {
      ii res = dnf(adj[node][i], node);
      cnt[node][i] = res.first;
      ptn[node][i] = res.second;
      chk[node][i] = true;
    }

    n += cnt[node][i];
    p *= finv[cnt[node][i]];
    p *= modint(ptn[node][i]);
  }
  p *= fac[n];
  return ii(n + 1, p.x);
}

void solve() {
  init();
  REP(i, N) {
    int n = adj[i].size();
    cnt[i] = vi(n, 0);
    ptn[i] = vi(n, 1);
    chk[i] = vector<bool>(n, false);
  }
  REP(i, N) cout << dnf(i, -1).second << endl;
}

int main() {
  cin >> N;
  REP(i, N - 1) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  solve();
}