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

#include <bits/stdc++.h>
#include <boost/format.hpp>
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/optional.hpp>

#ifdef DEBUG
#include "libs/debug.cpp"
#define DEBUG 1
#else
#define DEBUG 0
#endif

#define rep(i, n) repr((i), 0, (n))
#define repr(i, a, t) reps((i), (a), (t), 1)
#define reps(i, a, t, s)                                                       \\
  for (long long(i) = (a); (i) < (long long)(t); (i) += (s))
#define rrep(i, n) rrepr((i), (n), 0)
#define rrepr(i, a, t) rreps((i), (a), (t), 1)
#define rreps(i, a, t, s)                                                      \\
  for (long long(i) = (a)-1; (i) >= (long long)(t); (i) -= (s))
#define each(v, c) for (auto && (v) : (c))
#define all(c) (c).begin(), (c).end()

using namespace std;
namespace mp = boost::multiprecision;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using ml = mp::cpp_int;
template <typename T> using optional = boost::optional<T>;
const auto none = boost::none;
const long long MOD = 1e9 + 7;
const long long INF = 1e18;

/**
 * 0!, 1!, 2!, ..., max!
 * @param max
 * @param mod
 * @return
 */
vector<long long> get_factorials(long long max, long long mod = 0) {
  vector<long long> ret(max + 1, 1);
  long long n = 1;
  if (mod > 0) {
    for (long long i = 1; i <= max; ++i) {
      n *= i;
      n %= mod;
      ret[i] = n;
    }
  } else {
    for (long long i = 1; i <= max; ++i) {
      n *= i;
      ret[i] = n;
    }
  }
  return ret;
}

/**
 * 0 から max までの逆元
 * @param max
 * @param mod
 * @return
 */
vector<long long> mod_invs(long long max, long long mod) {
  vector<long long> invs(max + 1, 1);
  for (long long x = 2; x <= max; ++x) {
    invs[x] = (mod - mod / x) * invs[mod % x] % mod;
  }
  return invs;
}

/**
 * 階乗 0!, 1!, 2!, ..., max! の逆元
 * @param max
 * @param mod
 * @return
 */
vector<long long> factorial_invs(long long max, long long mod) {
  vector<long long> ret;
  long long r = 1;
  for (const auto &inv : mod_invs(max, mod)) {
    r = r * inv % mod;
    ret.push_back(r);
  }
  ret[0] = 1;
  return ret;
}
long long mod_pow(long long x, long long y, long long mod) {
  long long ret = 1;
  while (y > 0) {
    if (y & 1) {
      ret = ret * x % mod;
    }
    x = x * x % mod;
    y >>= 1;
  }
  return ret;
}

// https://atcoder.jp/contests/abc160/submissions/11311177
tuple<ll, ll> solve(const vector<vector<ll>> &graph, ll v, ll p,
                    const vector<ll> &finvs, const vector<ll> &factorials,
                    vector<tuple<ll, ll, ll>> &memo,
                    vector<unordered_map<ll, tuple<ll, ll>>> &memo2) {
  if (memo2[v].count(p)) {
    ll aaa, bbb;
    tie(aaa, bbb) = memo2[v][p];
    if (aaa != -1) {
      return make_tuple(aaa, bbb);
    }
  }
  if (get<0>(memo[v]) >= 0) {
    ll ret, children_cnt, without;
    tie(ret, children_cnt, without) = memo[v];
    ll r, cnt;
    if (without >= 0) {
      tie(r, cnt) = solve(graph, without, v, finvs, factorials, memo, memo2);
      ret *= finvs[children_cnt];
      ret %= MOD;
      ret *= factorials[children_cnt + cnt];
      ret %= MOD;
      ret *= finvs[cnt];
      ret %= MOD;
      ret *= r;
      ret %= MOD;
      children_cnt += cnt;
      without = -1;
      memo[v] = make_tuple(ret, children_cnt, without);
    }
    if (p == -1)
      return make_tuple(ret, children_cnt + 1);
    tie(r, cnt) = solve(graph, p, v, finvs, factorials, memo, memo2);
    ret *= finvs[children_cnt];
    ret %= MOD;
    ret *= factorials[children_cnt - cnt];
    ret %= MOD;
    ret *= factorials[cnt];
    ret %= MOD;
    ret *= mod_pow(r, MOD - 2, MOD);
    ret %= MOD;
    return make_tuple(ret, children_cnt - cnt + 1);
  }

  ll ret = 1;
  vector<ll> children;
  each(u, graph[v]) {
    if (u == p)
      continue;
    ll r, cnt;
    tie(r, cnt) = solve(graph, u, v, finvs, factorials, memo, memo2);
    children.push_back(cnt);
    ret *= r;
    ret %= MOD;
  }
  ll children_cnt = 0;
  each(cnt, children) {
    children_cnt += cnt;
    ret *= finvs[cnt];
    ret %= MOD;
  }
  ret *= factorials[children_cnt];
  ret %= MOD;

  memo[v] = make_tuple(ret, children_cnt, p);
  memo2[v][p] = make_tuple(ret, children_cnt + 1);
  return make_tuple(ret, children_cnt + 1);
}

int main() {
  cout << fixed << setprecision(10);
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  ifstream ifs;
  if (DEBUG) {
    ifs.open("src/_in.txt");
    cin.rdbuf(ifs.rdbuf());
  }

  ll N;
  cin >> N;
  vector<tuple<ll, ll>> AB(N);
  rep(i, N) { cin >> get<0>(AB[i]) >> get<1>(AB[i]); }

  vector<vector<ll>> graph(N, vector<ll>());
  rep(i, N - 1) {
    ll x, y;
    tie(x, y) = AB[i];
    x -= 1;
    y -= 1;
    graph[x].push_back(y);
    graph[y].push_back(x);
  }

  auto factorials = get_factorials(N * 2, MOD);
  auto finvs = factorial_invs(N * 2, MOD);

  vector<tuple<ll, ll, ll>> memo(N, make_tuple(-1, -1, -1));
  vector<unordered_map<ll, tuple<ll, ll>>> memo2(
      N, unordered_map<ll, tuple<ll, ll>>());

  rep(v, N) {
    ll ans, _;
    tie(ans, _) = solve(graph, v, -1, finvs, factorials, memo, memo2);
    cout << ans << "\\n";
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#include <boost/format.hpp>
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/optional.hpp>

#ifdef DEBUG
#include "libs/debug.cpp"
#define DEBUG 1
#else
#define DEBUG 0
#endif

#define rep(i, n) repr((i), 0, (n))
#define repr(i, a, t) reps((i), (a), (t), 1)
#define reps(i, a, t, s)                                                       \\
  for (long long(i) = (a); (i) < (long long)(t); (i) += (s))
#define rrep(i, n) rrepr((i), (n), 0)
#define rrepr(i, a, t) rreps((i), (a), (t), 1)
#define rreps(i, a, t, s)                                                      \\
  for (long long(i) = (a)-1; (i) >= (long long)(t); (i) -= (s))
#define each(v, c) for (auto && (v) : (c))
#define all(c) (c).begin(), (c).end()

using namespace std;
namespace mp = boost::multiprecision;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using ml = mp::cpp_int;
template <typename T> using optional = boost::optional<T>;
const auto none = boost::none;
const long long MOD = 1e9 + 7;
const long long INF = 1e18;

/**
 * 0!, 1!, 2!, ..., max!
 * @param max
 * @param mod
 * @return
 */
vector<long long> get_factorials(long long max, long long mod = 0) {
  vector<long long> ret(max + 1, 1);
  long long n = 1;
  if (mod > 0) {
    for (long long i = 1; i <= max; ++i) {
      n *= i;
      n %= mod;
      ret[i] = n;
    }
  } else {
    for (long long i = 1; i <= max; ++i) {
      n *= i;
      ret[i] = n;
    }
  }
  return ret;
}

/**
 * 0 から max までの逆元
 * @param max
 * @param mod
 * @return
 */
vector<long long> mod_invs(long long max, long long mod) {
  vector<long long> invs(max + 1, 1);
  for (long long x = 2; x <= max; ++x) {
    invs[x] = (mod - mod / x) * invs[mod % x] % mod;
  }
  return invs;
}

/**
 * 階乗 0!, 1!, 2!, ..., max! の逆元
 * @param max
 * @param mod
 * @return
 */
vector<long long> factorial_invs(long long max, long long mod) {
  vector<long long> ret;
  long long r = 1;
  for (const auto &inv : mod_invs(max, mod)) {
    r = r * inv % mod;
    ret.push_back(r);
  }
  ret[0] = 1;
  return ret;
}

tuple<ll, ll> solve(const vector<vector<ll>> &graph, ll v, ll p,
                    const vector<ll> &finvs, const vector<ll> &factorials,
                    vector<tuple<ll, ll, ll>> &memo,
                    vector<unordered_map<ll, tuple<ll, ll>>> &memo2) {
  if (memo2[v].count(p)) {
    ll aaa, bbb;
    tie(aaa, bbb) = memo2[v][p];
    if (aaa != -1) {
      return make_tuple(aaa, bbb);
    }
  }

  ll ret = 1;
  vector<ll> children;
  each(u, graph[v]) {
    if (u == p)
      continue;
    ll r, cnt;
    tie(r, cnt) = solve(graph, u, v, finvs, factorials, memo, memo2);
    children.push_back(cnt);
    ret *= r;
    ret %= MOD;
  }
  ll children_cnt = 0;
  each(cnt, children) {
    children_cnt += cnt;
    ret *= finvs[cnt];
    ret %= MOD;
  }
  ret *= factorials[children_cnt];
  ret %= MOD;

  memo[v] = make_tuple(ret, children_cnt, p);
  memo2[v][p] = make_tuple(ret, children_cnt + 1);
  return make_tuple(ret, children_cnt + 1);
}

int main() {
  cout << fixed << setprecision(10);
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  ifstream ifs;
  if (DEBUG) {
    ifs.open("src/_in.txt");
    cin.rdbuf(ifs.rdbuf());
  }

  ll N;
  cin >> N;
  vector<tuple<ll, ll>> AB(N);
  rep(i, N) { cin >> get<0>(AB[i]) >> get<1>(AB[i]); }

  vector<vector<ll>> graph(N, vector<ll>());
  rep(i, N - 1) {
    ll x, y;
    tie(x, y) = AB[i];
    x -= 1;
    y -= 1;
    graph[x].push_back(y);
    graph[y].push_back(x);
  }

  auto factorials = get_factorials(N * 2, MOD);
  auto finvs = factorial_invs(N * 2, MOD);

  vector<tuple<ll, ll, ll>> memo(N, make_tuple(-1, -1, -1));
  vector<unordered_map<ll, tuple<ll, ll>>> memo2(
      N, unordered_map<ll, tuple<ll, ll>>());

  rep(v, N) {
    ll ans, _;
    tie(ans, _) = solve(graph, v, -1, finvs, factorials, memo, memo2);
    cout << ans << "\\n";
  }
}