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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, n) for (ll i = 0; i < ((ll)(n)); i++)
#define reg(i, a, b) for (ll i = ((ll)(a)); i <= ((ll)(b)); i++)
#define irep(i, n) for (ll i = ((ll)(n)-1); i >= 0; i--)
#define ireg(i, a, b) for (ll i = ((ll)(b)); i >= ((ll)(a)); i--)
template <class T = int> using V = vector<T>;
template <class T = int> using VV = V<V<T>>;
template <class T = int> void print(vector<T> v) {
  for (auto a : v)
    cout << a << " ";
  cout << endl;
}

/*
 */

template <int MOD> struct ModInt {
  static const int Mod = MOD;
  unsigned x;
  ModInt() : x(0) {}
  ModInt(signed sig) {
    int sigt = sig % MOD;
    if (sigt < 0)
      sigt += MOD;
    x = sigt;
  }
  ModInt(signed long long sig) {
    int sigt = sig % MOD;
    if (sigt < 0)
      sigt += MOD;
    x = sigt;
  }
  int get() const { return (int)x; }

  ModInt &operator+=(ModInt that) {
    if ((x += that.x) >= MOD)
      x -= MOD;
    return *this;
  }
  ModInt &operator-=(ModInt that) {
    if ((x += MOD - that.x) >= MOD)
      x -= MOD;
    return *this;
  }
  ModInt &operator*=(ModInt that) {
    x = (unsigned long long)x * that.x % MOD;
    return *this;
  }
  ModInt &operator/=(ModInt that) { return *this *= that.inverse(); }
  ModInt operator+(ModInt that) const { return ModInt(*this) += that; }
  ModInt operator-(ModInt that) const { return ModInt(*this) -= that; }
  ModInt operator*(ModInt that) const { return ModInt(*this) *= that; }
  ModInt operator/(ModInt that) const { return ModInt(*this) /= that; }
  ModInt inverse() const {
    signed a = x, b = MOD, u = 1, v = 0;
    while (b) {
      signed t = a / b;
      a -= t * b;
      std::swap(a, b);
      u -= t * v;
      std::swap(u, v);
    }
    if (u < 0)
      u += Mod;
    ModInt res;
    res.x = (unsigned)u;
    return res;
  }
};
typedef ModInt<1000000007> mint;

ll n, visited[200010] = {};
V<ll> v[200010], v_rev[200010];
V<pair<mint, mint>> dp[200010], ru[200010], ru_inv[200010];
mint nf = 1;

pair<mint, mint> f(ll p, ll rev, bool begin) {
  ll k = v[p].size();
  mint sum = 1, ans = 1;
  if (visited[p] < k) {
    rep(i, k) {
      if (i == rev)
        continue;
      if (dp[p][i].first.get() == 0) {
        dp[p][i] = f(v[p][i], v_rev[p][i], false);
        visited[p]++;
      }
      sum += dp[p][i].first;
      ans *= dp[p][i].second;
    }
  } else {
    if (visited[p] == k) { // 累積和未計算
      ru[p][0] = dp[p][0];
      reg(i, 1, k - 1) {
        ru[p][i].first = dp[p][i].first + ru[p][i - 1].first;
        ru[p][i].second = dp[p][i].second * ru[p][i - 1].second;
      }
      ru_inv[p][k - 1] = dp[p][k - 1];
      irep(i, k - 1) {
        ru_inv[p][i].first = dp[p][i].first + ru_inv[p][i + 1].first;
        ru_inv[p][i].second = dp[p][i].second * ru_inv[p][i + 1].second;
      }
      visited[p] += 10;
    }
    if (begin) { // 最初だけは全方向の積が答え
      sum += ru[p][k - 1].first;
      ans *= ru[p][k - 1].second;
    } else {
      if (rev > 0) {
        sum += ru[p][rev - 1].first;
        ans *= ru[p][rev - 1].second;
      }
      if (rev < k - 1) {
        sum += ru_inv[p][rev + 1].first;
        ans *= ru_inv[p][rev + 1].second;
      }
    }
  }
  // printf("(%lld,%lld) = (%lld,%lld)\\n",par,id,sum.get(),(ans*sum).get());
  return {sum, ans * sum};
}

int main(void) {
  cin >> n;
  rep(i, n - 1) {
    ll a, b;
    cin >> a >> b;
    v[a].push_back(b);
    v[b].push_back(a);
    v_rev[a].push_back(v[b].size() - 1);
    v_rev[b].push_back(v[a].size() - 1);
    dp[a].push_back({0, 0});
    dp[b].push_back({0, 0});
    ru[a].push_back({0, 0});
    ru_inv[a].push_back({0, 0});
    ru[b].push_back({0, 0});
    ru_inv[b].push_back({0, 0});
  }
  reg(i, 1, n) nf *= i;
  reg(i, 1, n) { cout << (nf / f(i, -1, true).second).get() << endl; }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, n) for (ll i = 0; i < ((ll)(n)); i++)
#define reg(i, a, b) for (ll i = ((ll)(a)); i <= ((ll)(b)); i++)
#define irep(i, n) for (ll i = ((ll)(n)-1); i >= 0; i--)
#define ireg(i, a, b) for (ll i = ((ll)(b)); i >= ((ll)(a)); i--)
template <class T = int> using V = vector<T>;
template <class T = int> using VV = V<V<T>>;
template <class T = int> void print(vector<T> v) {
  for (auto a : v)
    cout << a << " ";
  cout << endl;
}

/*
 */

template <int MOD> struct ModInt {
  static const int Mod = MOD;
  unsigned x;
  ModInt() : x(0) {}
  ModInt(signed sig) {
    int sigt = sig % MOD;
    if (sigt < 0)
      sigt += MOD;
    x = sigt;
  }
  ModInt(signed long long sig) {
    int sigt = sig % MOD;
    if (sigt < 0)
      sigt += MOD;
    x = sigt;
  }
  int get() const { return (int)x; }

  ModInt &operator+=(ModInt that) {
    if ((x += that.x) >= MOD)
      x -= MOD;
    return *this;
  }
  ModInt &operator-=(ModInt that) {
    if ((x += MOD - that.x) >= MOD)
      x -= MOD;
    return *this;
  }
  ModInt &operator*=(ModInt that) {
    x = (unsigned long long)x * that.x % MOD;
    return *this;
  }
  ModInt &operator/=(ModInt that) { return *this *= that.inverse(); }
  ModInt operator+(ModInt that) const { return ModInt(*this) += that; }
  ModInt operator-(ModInt that) const { return ModInt(*this) -= that; }
  ModInt operator*(ModInt that) const { return ModInt(*this) *= that; }
  ModInt operator/(ModInt that) const { return ModInt(*this) /= that; }
  ModInt inverse() const {
    signed a = x, b = MOD, u = 1, v = 0;
    while (b) {
      signed t = a / b;
      a -= t * b;
      std::swap(a, b);
      u -= t * v;
      std::swap(u, v);
    }
    if (u < 0)
      u += Mod;
    ModInt res;
    res.x = (unsigned)u;
    return res;
  }
};
typedef ModInt<1000000007> mint;

ll n;
V<ll> v[200010];
V<pair<mint, mint>> dp[200010];
mint nf = 1;

pair<mint, mint> f(ll par, ll id) {
  if (dp[par][id].first.get() != 0)
    return dp[par][id];
  ll p = v[par][id];
  // cerr<<p<<endl;
  mint sum = 1, ans = 1;
  if (v[p].size() == 1)
    return dp[par][id] = {1, 1};
  rep(i, v[p].size()) {
    if (v[p][i] == par)
      continue;
    auto q = f(p, i);
    sum += q.first;
    ans *= q.second;
  }
  // printf("(%lld,%lld) = (%lld,%lld)\\n",par,id,sum.get(),(ans*sum).get());
  return dp[par][id] = {sum, ans * sum};
}

int main(void) {
  cin >> n;
  rep(i, n - 1) {
    ll a, b;
    cin >> a >> b;
    v[a].push_back(b);
    v[b].push_back(a);
    dp[a].push_back({0, 0});
    dp[b].push_back({0, 0});
  }
  reg(i, 1, n) nf *= i;
  // cerr<<nf.get()<<endl;
  reg(i, 1, n) {
    // cerr<<"今"<<i<<endl;
    mint ans = 1;
    rep(j, v[i].size()) {
      auto p = f(i, j);
      ans *= p.second;
    }
    ans *= n;
    cout << (nf / ans).get() << endl;
  }
  return 0;
}