Problem p02728 (C++) — buggy submission, verdict: Runtime Error

#ifndef DEBUG
#define NDEBUG
#endif
#include <algorithm>
#include <cassert>
#include <iostream>
#include <iterator>
#include <limits>
#include <numeric>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>

using namespace std;

// template {{{
// misc {{{
using Z = long long;
[[maybe_unused]] constexpr Z INF = numeric_limits<Z>::max() / 3;
// }}}

// debug {{{
template <class T>
using enable_if_sequence_t = enable_if_t<
    is_same<typename iterator_traits<typename remove_cv_t<
                remove_reference_t<T>>::iterator>::iterator_category,
            random_access_iterator_tag>{}>;
#ifdef NDEBUG
#define dump(x)
#define debug if (0)
template <class T> inline T &&ix(T &&value) { return value; }
template <class T, class Index, class... Indices,
          class = enable_if_sequence_t<T>>
inline auto &&ix(T &&container, Index index, Indices... indices) {
  return ix(container[index], indices...);
}
#else
#define dump(x)                                                                \\
  do {                                                                         \\
    cerr << "\\e[33m[dump: " << __LINE__ << "] " << (#x) << " = " << x          \\
         << "\\e[0m" << endl;                                                   \\
  } while (0);
#define debug
template <class T>
inline auto &&ix_impl([[maybe_unused]] int line,
                      [[maybe_unused]] const char *code, T &&value) {
  return value;
}
template <class T, class Index, class... Indices,
          class = enable_if_sequence_t<T>>
inline auto &&ix_impl(int line, const char *code, T &&container, Index index,
                      Indices... indices) {
  if (index < 0) {
    cerr << "\\e[31mix: negative index at line " << line << ", ix(" << code
         << ")\\e[0m" << endl;
    exit(1);
  }
  int size = container.size();
  if (index >= size) {
    cerr << "\\e[31mix: index out of range at line " << line << ", ix(" << code
         << ")\\n"
         << "index = " << index << " whereas size = " << size << "\\e[0m"
         << endl;
    exit(1);
  }
  return ix_impl(line, code, container[index], indices...);
}
#define ix(...) ix_impl(__LINE__, #__VA_ARGS__, __VA_ARGS__)
#endif
// }}}

// IO {{{
template <class T, class U> ostream &operator<<(ostream &os, pair<T, U> p) {
  os << '(' << p.first << ", " << p.second << ')';
  return os;
}
template <class T, class U> istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}
template <class T> false_type is_container_impl(...);
template <class T, class = typename T::iterator> true_type is_container_impl(T);
template <class T>
struct is_container : decltype(is_container_impl<T>(declval<T>())) {};
template <> struct is_container<string> : std::false_type {};
template <class Container, class = enable_if_t<is_container<Container>{}>>
istream &operator>>(istream &is, Container &cont) {
  for (auto &v : cont)
    is >> v;
  return is;
}
template <class Container, class = enable_if_t<is_container<Container>{}>>
ostream &operator<<(ostream &os, Container const &cont) {
  bool first = true;
  constexpr char sep =
      is_container<typename Container::value_type>{} ? '\\n' : ' ';
  for (auto const &v : cont) {
    if (!first) {
      os << sep;
    }
    first = false;
    os << v;
  }
  return os;
}
// }}}
// }}}

// bpow {{{
template <class T> T bpow(T x, int k) {
  if (k == 0)
    return T(1);
  auto const &prev = bpow(x, k / 2);
  if (k % 2 == 0)
    return prev * prev;
  else
    return prev * prev * x;
}
// }}}
// {{{ extgcd
template <class T> struct extgcd_solution {
  T gcd, x, y;
};

template <class T = Z> constexpr extgcd_solution<T> extgcd(T a, T b) {
  if (b == 0)
    return {a, 1, 0};
  if (a < b) {
    auto res = extgcd(b, a);
    return {res.gcd, res.y, res.x};
  }
  auto prev = extgcd(b, a % b);
  return {prev.gcd, prev.y, prev.x - prev.y * (a / b)};
}
// }}}
// Mod {{{
template <class T = Z, T mod = 1000000007> class Mod {
private:
  T value;

public:
  constexpr Mod() : value(0) {}
  constexpr Mod(T original)
      : value(original >= 0 ? original % mod
                            : ((1 - original / mod) * mod + original)) {}
  inline constexpr operator T() const { return value; }
  inline constexpr Mod inv() const {
    auto &&res = extgcd(value, mod);
    assert(res.gcd == 1);
    return Mod(res.x);
  }
  inline constexpr Mod operator+(Mod const m) const {
    return Mod(value + m.value);
  }
  inline constexpr Mod operator-(Mod const m) const {
    return Mod(value - m.value);
  }
  inline constexpr Mod operator*(Mod const m) const {
    long long prod = value;
    prod *= m.value;
    prod %= mod;
    return Mod(static_cast<T>(prod));
  }
  inline constexpr Mod operator/(Mod const m) const { return *this * m.inv(); }
  inline constexpr Mod operator+(T m) const { return Mod(value + (m % mod)); }
  inline constexpr Mod operator-(T m) const { return Mod(value - m); }
  inline constexpr Mod operator*(T m) const {
    long long prod = value;
    prod *= m % mod;
    prod %= mod;
    return Mod(static_cast<T>(prod));
  }
  inline constexpr Mod operator/(T m) const { return *this * Mod(m).inv(); }
  inline constexpr Mod pow(int k) const {
    return k >= 0 ? bpow(*this, k) : bpow(inv(), -k);
  }
  inline ostream &operator<<(ostream &os) {
    os << '[' << value << ']';
    return os;
  }
  inline istream &operator>>(istream &is) {
    is >> value;
    return is;
  }
};

template <class T, T mod>
inline constexpr Mod<T, mod> operator+(T n, Mod<T, mod> m) {
  return m + n;
}
template <class T, T mod>
inline constexpr Mod<T, mod> operator-(T n, Mod<T, mod> m) {
  return Mod<T, mod>(n) - m;
}
template <class T, T mod>
inline constexpr Mod<T, mod> operator*(T n, Mod<T, mod> m) {
  return m * n;
}
template <class T, T mod>
inline constexpr Mod<T, mod> operator/(T n, Mod<T, mod> m) {
  return Mod<T, mod>(n) / m;
}
template <class T, T mod, class R>
inline Mod<T, mod> &operator+=(Mod<T, mod> &m, R rhs) {
  return m = m + rhs;
}
template <class T, T mod, class R>
inline Mod<T, mod> &operator-=(Mod<T, mod> &m, R rhs) {
  return m = m - rhs;
}
template <class T, T mod, class R>
inline Mod<T, mod> &operator*=(Mod<T, mod> &m, R rhs) {
  return m = m * rhs;
}
template <class T, T mod, class R>
inline Mod<T, mod> &operator/=(Mod<T, mod> &m, R rhs) {
  return m = m / rhs;
}
// }}}

// Combinations {{{
template <class T> class Combinations {
private:
  vector<T> factorials;

public:
  Combinations(int maximum) : factorials(maximum + 1) {
    factorials[0] = 1;
    for (auto i = 1; i <= maximum; i++)
      factorials[i] = factorials[i - 1] * T(i);
  }
  inline T factorial(int n) { return ix(factorials, n); }
  inline T permutation(int n, int r) {
    return ix(factorials, n) / ix(factorials, r);
  }
  inline T combination(int n, int r) {
    return ix(factorials, n) / (ix(factorials, r) * ix(factorials, n - r));
  }
  inline T homogeneous(int n, int r) { return combination(n + r - 1, r); }
};
// }}}

using MZ = Mod<>;
using Graph = vector<vector<Z>>;

Combinations<MZ> comb(1000000);

pair<vector<Z>, vector<Z>> order(Graph const &tree, Z root) {
  vector<Z> result = {root};
  vector<Z> parent(tree.size(), -1);
  auto dfs_aux = [&](auto &&self, Z pos, Z from) -> void {
    auto dfs = [&](auto... args) { self(self, args...); };
    for (auto &&v : ix(tree, pos)) {
      if (v == from)
        continue;
      result.push_back(v);
      ix(parent, v) = pos;
      dfs(v, pos);
    }
  };
  auto dfs = [&](auto... args) { dfs_aux(dfs_aux, args...); };
  dfs(root, -1);
  return {result, parent};
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.precision(10);
  cout << fixed;
  Z N;
  cin >> N;
  Graph gr(N);
  for (auto i = 0; i < N - 1; i++) {
    Z a, b;
    cin >> a >> b;
    a--;
    b--;
    ix(gr, a).push_back(b);
    ix(gr, b).push_back(a);
  }
  vector<Z> ordered, parent;
  tie(ordered, parent) = order(gr, 0);
  dump(ordered);
  dump(parent);
  vector<Z> vertices(N, 1);
  for_each(rbegin(ordered), rend(ordered) - 1,
           [&](Z i) { ix(vertices, ix(parent, i)) += ix(vertices, i); });
  dump(vertices);
  vector<MZ> dp(N, 1);
  for_each(rbegin(ordered), rend(ordered), [&](Z i) {
    ix(dp, i) *= comb.factorial(ix(vertices, i) - 1);
    for (auto &&ch : ix(gr, i)) {
      if (ch == ix(parent, i))
        continue;
      ix(dp, i) *= ix(dp, ch);
      ix(dp, i) /= comb.factorial(ix(vertices, ch));
    }
  });
  dump(dp);
  vector<MZ> ans = dp;
  for (auto &&i : ordered) {
    if (i == 0)
      continue;
    dump(i);
    Z p = ix(parent, i);
    ix(ans, i) *= comb.combination(N - 1, ix(vertices, i) - 1);
    dump(ix(ans, i));
    MZ pdp = ix(ans, p);
    pdp /= comb.combination(N - 1, ix(vertices, i));
    dump(pdp);
    pdp /= ix(dp, i);
    dump(pdp);
    ix(ans, i) *= pdp;
  }
  for (auto &&a : ans)
    cout << a << '\\n';
}


Error: 0

Fixed submission:

#ifndef DEBUG
#define NDEBUG
#endif
#include <algorithm>
#include <cassert>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <numeric>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

using namespace std;

// template {{{
// misc {{{
using Z = long long;
[[maybe_unused]] constexpr Z INF = numeric_limits<Z>::max() / 3;
// }}}

// debug {{{
template <class T>
using enable_if_sequence_t = enable_if_t<
    is_same<typename iterator_traits<typename remove_cv_t<
                remove_reference_t<T>>::iterator>::iterator_category,
            random_access_iterator_tag>{}>;
#ifdef NDEBUG
#define dump(x)
#define debug if (0)
template <class T> inline T &&ix(T &&value) { return value; }
template <class T, class Index, class... Indices,
          class = enable_if_sequence_t<T>>
inline auto &&ix(T &&container, Index index, Indices... indices) {
  return ix(container[index], indices...);
}
#else
#define dump(x)                                                                \\
  do {                                                                         \\
    cerr << "\\e[33m[dump: " << __LINE__ << "] " << (#x) << " = " << x          \\
         << "\\e[0m" << endl;                                                   \\
  } while (0);
#define debug
template <class T>
inline auto &&ix_impl([[maybe_unused]] int line,
                      [[maybe_unused]] const char *code, T &&value) {
  return value;
}
template <class T, class Index, class... Indices,
          class = enable_if_sequence_t<T>>
inline auto &&ix_impl(int line, const char *code, T &&container, Index index,
                      Indices... indices) {
  if (index < 0) {
    cerr << "\\e[31mix: negative index at line " << line << ", ix(" << code
         << ")\\e[0m" << endl;
    exit(1);
  }
  int size = container.size();
  if (index >= size) {
    cerr << "\\e[31mix: index out of range at line " << line << ", ix(" << code
         << ")\\n"
         << "index = " << index << " whereas size = " << size << "\\e[0m"
         << endl;
    exit(1);
  }
  return ix_impl(line, code, container[index], indices...);
}
#define ix(...) ix_impl(__LINE__, #__VA_ARGS__, __VA_ARGS__)
#endif
// }}}

// IO {{{
template <class T, class U> ostream &operator<<(ostream &os, pair<T, U> p) {
  os << '(' << p.first << ", " << p.second << ')';
  return os;
}
template <class T, class U> istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}
template <class T> false_type is_container_impl(...);
template <class T, class = typename T::iterator> true_type is_container_impl(T);
template <class T>
struct is_container : decltype(is_container_impl<T>(declval<T>())) {};
template <> struct is_container<string> : std::false_type {};
template <class Container, class = enable_if_t<is_container<Container>{}>>
istream &operator>>(istream &is, Container &cont) {
  for (auto &v : cont)
    is >> v;
  return is;
}
template <class Container, class = enable_if_t<is_container<Container>{}>>
ostream &operator<<(ostream &os, Container const &cont) {
  bool first = true;
  constexpr char sep =
      is_container<typename Container::value_type>{} ? '\\n' : ' ';
  for (auto const &v : cont) {
    if (!first) {
      os << sep;
    }
    first = false;
    os << v;
  }
  return os;
}
// }}}
// }}}

// bpow {{{
template <class T> T bpow(T x, int k) {
  if (k == 0)
    return T(1);
  auto const &prev = bpow(x, k / 2);
  if (k % 2 == 0)
    return prev * prev;
  else
    return prev * prev * x;
}
// }}}
// {{{ extgcd
template <class T> struct extgcd_solution {
  T gcd, x, y;
};

template <class T = Z> constexpr extgcd_solution<T> extgcd(T a, T b) {
  if (b == 0)
    return {a, 1, 0};
  if (a < b) {
    auto res = extgcd(b, a);
    return {res.gcd, res.y, res.x};
  }
  auto prev = extgcd(b, a % b);
  return {prev.gcd, prev.y, prev.x - prev.y * (a / b)};
}
// }}}
// Mod {{{
template <class T = Z, T mod = 1000000007> class Mod {
private:
  T value;

public:
  constexpr Mod() : value(0) {}
  constexpr Mod(T original)
      : value(original >= 0 ? original % mod
                            : ((1 - original / mod) * mod + original)) {}
  inline constexpr operator T() const { return value; }
  inline constexpr Mod inv() const {
    auto &&res = extgcd(value, mod);
    assert(res.gcd == 1);
    return Mod(res.x);
  }
  inline constexpr Mod operator+(Mod const m) const {
    return Mod(value + m.value);
  }
  inline constexpr Mod operator-(Mod const m) const {
    return Mod(value - m.value);
  }
  inline constexpr Mod operator*(Mod const m) const {
    long long prod = value;
    prod *= m.value;
    prod %= mod;
    return Mod(static_cast<T>(prod));
  }
  inline constexpr Mod operator/(Mod const m) const { return *this * m.inv(); }
  inline constexpr Mod operator+(T m) const { return Mod(value + (m % mod)); }
  inline constexpr Mod operator-(T m) const { return Mod(value - m); }
  inline constexpr Mod operator*(T m) const {
    long long prod = value;
    prod *= m % mod;
    prod %= mod;
    return Mod(static_cast<T>(prod));
  }
  inline constexpr Mod operator/(T m) const { return *this * Mod(m).inv(); }
  inline constexpr Mod pow(int k) const {
    return k >= 0 ? bpow(*this, k) : bpow(inv(), -k);
  }
  inline ostream &operator<<(ostream &os) {
    os << '[' << value << ']';
    return os;
  }
  inline istream &operator>>(istream &is) {
    is >> value;
    return is;
  }
};

template <class T, T mod>
inline constexpr Mod<T, mod> operator+(T n, Mod<T, mod> m) {
  return m + n;
}
template <class T, T mod>
inline constexpr Mod<T, mod> operator-(T n, Mod<T, mod> m) {
  return Mod<T, mod>(n) - m;
}
template <class T, T mod>
inline constexpr Mod<T, mod> operator*(T n, Mod<T, mod> m) {
  return m * n;
}
template <class T, T mod>
inline constexpr Mod<T, mod> operator/(T n, Mod<T, mod> m) {
  return Mod<T, mod>(n) / m;
}
template <class T, T mod, class R>
inline Mod<T, mod> &operator+=(Mod<T, mod> &m, R rhs) {
  return m = m + rhs;
}
template <class T, T mod, class R>
inline Mod<T, mod> &operator-=(Mod<T, mod> &m, R rhs) {
  return m = m - rhs;
}
template <class T, T mod, class R>
inline Mod<T, mod> &operator*=(Mod<T, mod> &m, R rhs) {
  return m = m * rhs;
}
template <class T, T mod, class R>
inline Mod<T, mod> &operator/=(Mod<T, mod> &m, R rhs) {
  return m = m / rhs;
}
// }}}

using MZ = Mod<>;

// Combinations {{{
template <class T> class Combinations {
private:
  vector<T> factorials;

public:
  Combinations(int maximum) : factorials(maximum + 1) {
    factorials[0] = 1;
    for (auto i = 1; i <= maximum; i++)
      factorials[i] = factorials[i - 1] * T(i);
  }
  inline T factorial(int n) { return ix(factorials, n); }
  inline T permutation(int n, int r) {
    return ix(factorials, n) / ix(factorials, r);
  }
  inline T combination(int n, int r) {
    return ix(factorials, n) / (ix(factorials, r) * ix(factorials, n - r));
  }
  inline T homogeneous(int n, int r) { return combination(n + r - 1, r); }
};
// }}}

using Graph = vector<vector<Z>>;
vector<map<Z, MZ>> dp;
vector<map<Z, Z>> vdp;
vector<MZ> dp2;
vector<Z> dprev;

Z vertices(Graph const &gr, Z pos, Z prev) {
  if (pos == -1)
    return 0;
  if (ix(vdp, pos).count(prev))
    return ix(vdp, pos)[prev];
  Z &res = ix(vdp, pos)[prev] = 1;
  for (auto &&v : ix(gr, pos)) {
    if (v == prev)
      continue;
    res += vertices(gr, v, pos);
  }
  return res;
}

MZ patterns(Graph const &gr, Z pos, Z prev, Combinations<MZ> &comb) {
  if (pos == -1)
    return 1;
  dump(pos);
  dump(prev);
  if (ix(dp, pos).count(prev))
    return ix(dp, pos)[prev];
  if (!ix(dp, pos).empty()) {
    MZ &res = ix(dp, pos)[prev];
    res = ix(dp2, pos);
    // res *= patterns(gr, ix(dprev, pos), pos, comb);
    res *= comb.factorial(gr.size() - 1 - vertices(gr, prev, pos));
    res /= patterns(gr, prev, pos, comb);
    res *= comb.factorial(vertices(gr, prev, pos));
    return res;
  }
  ix(dprev, pos) = prev;
  dump(pos);
  dump(prev);
  MZ res = 1;
  vector<Z> vs;
  Z total = 0;
  for (auto &&v : ix(gr, pos)) {
    if (v == prev)
      continue;
    res *= patterns(gr, v, pos, comb);
    Z vc = vertices(gr, v, pos);
    vs.push_back(vc);
    total += vc;
  }
  MZ &memo = ix(dp2, pos) = res;
  dump(vs);
  dump(res);
  Z remaining = total;
  for (auto &&v : vs) {
    res *= comb.combination(remaining, v);
    memo /= comb.factorial(v);
    remaining -= v;
  }
  memo /= comb.factorial(vertices(gr, prev, pos));
  ix(dp, pos)[prev] = res;
  memo *= patterns(gr, prev, pos, comb);
  dump(res);
  return ix(dp, pos)[prev] = res;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.precision(10);
  cout << fixed;
  Z N;
  cin >> N;
  Graph graph(N);
  for (auto i = 0; i < N - 1; i++) {
    Z a, b;
    cin >> a >> b;
    a--;
    b--;
    ix(graph, a).push_back(b);
    ix(graph, b).push_back(a);
  }
  dp.resize(N);
  vdp.resize(N);
  dp2.resize(N, -1);
  dprev.resize(N, -1);
  Combinations<MZ> comb(1000000);
  for (auto i = 0; i < N; i++) {
    cout << patterns(graph, i, -1, comb) << '\\n';
  }
  dump(dp);
  dump(vdp);
  dump(dp2);
  dump(dprev);
}