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

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define FOR_LT(i, beg, end) for (int i = (int)(beg); i < (int)(end); i++)
#define FOR_LE(i, beg, end) for (int i = (int)(beg); i <= (int)(end); i++)
#define FOR_DW(i, beg, end) for (int i = (int)(beg); (int)(end) <= i; i--)
#define REP(n) for (int repeat_index = 0; repeat_index < (int)n; repeat_index++)

using namespace std;

template <int64_t M = 1000000007> class ModInt {
public:
  ModInt() : val_(0){};

  ModInt(int64_t val) {
    this->val_ = val;
    this->val_ %= M;
    while (this->val_ >= M)
      this->val_ -= M;
  }

  operator int64_t() const { return this->val_; }

  ModInt &operator+=(int64_t val) {
    this->val_ += val;
    this->val_ %= M;
    if (this->val_ >= M)
      this->val_ -= M;

    return *this;
  }

  ModInt &operator-=(int64_t val) {
    this->val_ -= val;
    this->val_ %= M;
    if (this->val_ < 0)
      this->val_ += M;

    return *this;
  }

  ModInt &operator*=(int64_t val) {
    this->val_ *= val;
    this->val_ %= M;

    return *this;
  }

  ModInt &operator/=(int64_t val) {
    ModInt v = ModInt(val).pow(M - 2);
    *this *= v;

    return *this;
  }

  ModInt operator+(int64_t v) const {
    ModInt ret = *this;
    return (ret += v);
  }

  ModInt operator-(int64_t v) const {
    ModInt ret = *this;
    return (ret -= v);
  }

  ModInt operator*(int64_t v) const {
    ModInt ret = *this;
    return (ret *= v);
  }

  ModInt operator/(int64_t v) const {
    ModInt ret = *this;
    return (ret /= v);
  }

  ModInt pow(int64_t m) const {
    if (m == 0) {
      ModInt ret(1);
      return ret;
    }
    if (m == 1) {
      ModInt ret(*this);
      return ret;
    }

    ModInt v = this->pow(m / 2);
    ModInt ret = v * v;
    if (m & 1) {
      ret *= (*this);
    }
    return ret;
  }

  ostream &operator<<(ostream &out) {
    out << this->val_;
    return out;
  }

private:
  int64_t val_;
};

struct P {
  ModInt<> v;
  int n;
};

template <int64_t M = 1000000007> class NCR {
public:
  NCR(){};

  NCR(int n) {
    this->factors_ = vector<ModInt<M>>(n + 1);
    this->finvs_ = vector<ModInt<M>>(n + 1);

    {
      ModInt<M> f = 1;
      this->factors_[0] = 1;
      FOR_LE(i, 1, n) {
        f *= i;
        this->factors_[i] = f;
      }
    }
    {
      ModInt<M> inv = ModInt<M>(1) / this->factors_[n];
      this->finvs_[n] = inv;
      FOR_DW(i, n - 1, 0) {
        inv *= i + 1;
        this->finvs_[i] = inv;
      }
    }
  }

  ModInt<M> Value(int n, int k) {
    return this->factors_[n] * this->finvs_[n - k] * this->finvs_[k];
  }

  ModInt<M> Factor(int n) { return this->factors_[n]; }

  ModInt<M> Finv(int n) { return this->finvs_[n]; }

private:
  vector<ModInt<M>> factors_;
  vector<ModInt<M>> finvs_;
};

ModInt<> dp[200001];
int ps[200001];
int ns[200001];

NCR<> ncr;

void dfs1(vector<vector<int>> &es, int p) {
  ModInt<> v = 1;
  for (int np : es[p]) {
    if (np == ps[p])
      continue;

    ps[np] = p;
    dfs1(es, np);
    ns[p] += ns[np];
    v *= ncr.Value(ns[p], ns[np]);
    v *= dp[np];
  }
  dp[p] = v;
  ns[p]++;
}

void dfs2(vector<vector<int>> &es, int p, int n, ModInt<> pv) {
  dp[p] *= pv;
  dp[p] *= ncr.Value(n - 1, n - ns[p]);
  ModInt<> v = 1;
  for (int np : es[p]) {
    if (np == ps[p])
      continue;

    ModInt<> npv = dp[p] / dp[np] / ncr.Value(n - 1, ns[np]);
    dfs2(es, np, n, npv);
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout << fixed << setprecision(20);

  int n;
  cin >> n;

  ncr = NCR<>(n);

  vector<vector<int>> es(n + 1);
  REP(n - 1) {
    int a, b;
    cin >> a >> b;
    es[a].push_back(b);
    es[b].push_back(a);
  }

  dfs1(es, 1);
  dfs2(es, 1, n, 1);

  FOR_LE(i, 1, n) { cout << dp[i] << endl; }

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define FOR_LT(i, beg, end) for (int i = (int)(beg); i < (int)(end); i++)
#define FOR_LE(i, beg, end) for (int i = (int)(beg); i <= (int)(end); i++)
#define FOR_DW(i, beg, end) for (int i = (int)(beg); (int)(end) <= i; i--)
#define REP(n) for (int repeat_index = 0; repeat_index < (int)n; repeat_index++)

using namespace std;

template <int64_t M = 1000000007> class ModInt {
public:
  ModInt() : val_(0){};

  ModInt(int64_t val) {
    this->val_ = val;
    this->val_ %= M;
    while (this->val_ >= M)
      this->val_ -= M;
  }

  operator int64_t() const { return this->val_; }

  ModInt &operator+=(int64_t val) {
    this->val_ += val;
    this->val_ %= M;
    if (this->val_ >= M)
      this->val_ -= M;

    return *this;
  }

  ModInt &operator-=(int64_t val) {
    this->val_ -= val;
    this->val_ %= M;
    if (this->val_ < 0)
      this->val_ += M;

    return *this;
  }

  ModInt &operator*=(int64_t val) {
    this->val_ *= val;
    this->val_ %= M;

    return *this;
  }

  ModInt &operator/=(int64_t val) {
    ModInt v = ModInt(val).pow(M - 2);
    *this *= v;

    return *this;
  }

  ModInt operator+(int64_t v) const {
    ModInt ret = *this;
    return (ret += v);
  }

  ModInt operator-(int64_t v) const {
    ModInt ret = *this;
    return (ret -= v);
  }

  ModInt operator*(int64_t v) const {
    ModInt ret = *this;
    return (ret *= v);
  }

  ModInt operator/(int64_t v) const {
    ModInt ret = *this;
    return (ret /= v);
  }

  ModInt pow(int64_t m) const {
    if (m == 0) {
      ModInt ret(1);
      return ret;
    }
    if (m == 1) {
      ModInt ret(*this);
      return ret;
    }

    ModInt v = this->pow(m / 2);
    ModInt ret = v * v;
    if (m & 1) {
      ret *= (*this);
    }
    return ret;
  }

  ostream &operator<<(ostream &out) {
    out << this->val_;
    return out;
  }

private:
  int64_t val_;
};

struct P {
  ModInt<> v;
  int n;
};

template <int64_t M = 1000000007> class NCR {
public:
  NCR(){};

  NCR(int n) {
    this->factors_ = vector<ModInt<M>>(n + 1);
    this->finvs_ = vector<ModInt<M>>(n + 1);

    {
      ModInt<M> f = 1;
      this->factors_[0] = 1;
      FOR_LE(i, 1, n) {
        f *= i;
        this->factors_[i] = f;
      }
    }
    {
      ModInt<M> inv = ModInt<M>(1) / this->factors_[n];
      this->finvs_[n] = inv;
      FOR_DW(i, n - 1, 0) {
        inv *= i + 1;
        this->finvs_[i] = inv;
      }
    }
  }

  ModInt<M> Value(int n, int k) {
    return this->factors_[n] * this->finvs_[n - k] * this->finvs_[k];
  }

  ModInt<M> Factor(int n) { return this->factors_[n]; }

  ModInt<M> Finv(int n) { return this->finvs_[n]; }

private:
  vector<ModInt<M>> factors_;
  vector<ModInt<M>> finvs_;
};

ModInt<> dp[200001];
int ps[200001];
int ns[200001];

NCR<> ncr;

void dfs1(vector<vector<int>> es, int p) {
  ModInt<> v = 1;
  for (int np : es[p]) {
    if (np == ps[p])
      continue;

    ps[np] = p;
    dfs1(es, np);
    ns[p] += ns[np];
    v *= ncr.Value(ns[p], ns[np]);
    v *= dp[np];
  }
  dp[p] = v;
  ns[p]++;
}

void dfs2(vector<vector<int>> es, int p, int n, ModInt<> pv) {
  dp[p] *= pv;
  dp[p] *= ncr.Value(n - 1, n - ns[p]);
  ModInt<> v = 1;
  for (int np : es[p]) {
    if (np == ps[p])
      continue;

    ModInt<> npv = dp[p] / dp[np] / ncr.Value(n - 1, ns[np]);
    dfs2(es, np, n, npv);
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout << fixed << setprecision(20);

  int n;
  cin >> n;

  ncr = NCR<>(n);

  vector<vector<int>> es(n + 1);
  REP(n - 1) {
    int a, b;
    cin >> a >> b;
    es[a].push_back(b);
    es[b].push_back(a);
  }

  dfs1(es, 1);
  dfs2(es, 1, n, 1);

  FOR_LE(i, 1, n) { cout << dp[i] << endl; }

  return 0;
}