Problem p03181 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

#define M_PI 3.14159265358979323846 // pi

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<ll> VI;
typedef pair<ll, ll> P;
typedef tuple<ll, ll, ll> t3;
typedef tuple<ll, ll, ll, ll> t4;
typedef tuple<ll, ll, ll, ll, ll> t5;

#define rep(a, n) for (ll a = 0; a < n; a++)
#define repi(a, b, n) for (ll a = b; a < n; a++)

using namespace std;

static const ll INF = 1e15;

template <typename T> static inline void chmax(T &ref, const T value) {
  if (ref < value)
    ref = value;
}

const ll mod = 1000000007;

ll m = 1e9 + 7;

class modint {
  using u64 = std::int_fast64_t;

public:
  u64 a;
  modint(const u64 x = 0) noexcept : a(x % m) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= m) {
      a -= m;
    }
    return *this;
  }
  modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += m;
    }
    a -= rhs.a;
    return *this;
  }
  modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % m;
    return *this;
  }
};

ostream &operator<<(ostream &stream, const modint &data) {
  stream << data.a;
  return stream;
}

ll n;
vector<vector<int>> g;

vector<map<int, modint>> children;

modint dfs(int current, int prev) {
  // 頂点current が黒である組み合わせ
  modint i = 1;
  for (auto c : g[current]) {
    if (c == prev)
      continue;
    modint t = dfs(c, current) + 1;
    children[current][c] = t;
    i *= t;
  }
  return i;
}

vector<modint> dp1;

void dfs2(int current, int parent, modint pValue) {
  // 親ノードの情報マージ
  auto &child = children[current];
  if (parent != -1) {
    child[parent] = pValue + 1;
  }
  modint &ans = dp1[current];
  ans = 1;
  for (auto p : child) {
    ans *= p.second;
  }

  // publish
  auto csize = child.size();
  vector<int> next;
  for (auto p : child) {
    next.push_back(p.first);
  }
  auto b = child.begin();
  auto rb = child.rbegin();
  vector<modint> pos(csize);
  vector<modint> neg(csize);
  pos[0] = b->second;
  neg[csize - 1] = rb->second;
  for (int i = 1; i < csize; i++) {
    b++;
    rb++;
    pos[i] = pos[i - 1] * b->second;
    neg[csize - 1 - i] = neg[csize - i] * rb->second;
  }
  for (int i = 0; i < csize; i++) {
    if (next[i] == parent)
      continue;
    modint p = 1;
    if (i > 0) {
      p *= pos[i - 1];
    }
    if (i < csize - 1) {
      p *= neg[i + 1];
    }
    dfs2(next[i], current, p);
  }
}

int main() {
  cin >> n >> m;
  g.resize(n);
  dp1.resize(n);
  children.resize(n);
  rep(i, n - 1) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  dfs(0, -1);
  dfs2(0, -1, 0);
  rep(i, n) { cout << dp1[i] << endl; }
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>

#define M_PI 3.14159265358979323846 // pi

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<ll> VI;
typedef pair<ll, ll> P;
typedef tuple<ll, ll, ll> t3;
typedef tuple<ll, ll, ll, ll> t4;
typedef tuple<ll, ll, ll, ll, ll> t5;

#define rep(a, n) for (ll a = 0; a < n; a++)
#define repi(a, b, n) for (ll a = b; a < n; a++)

using namespace std;

static const ll INF = 1e15;

template <typename T> static inline void chmax(T &ref, const T value) {
  if (ref < value)
    ref = value;
}

const ll mod = 1000000007;

ll m = 1e9 + 7;

class modint {
  using u64 = std::int_fast64_t;

public:
  u64 a;
  modint(const u64 x = 0) noexcept : a(x % m) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= m) {
      a -= m;
    }
    return *this;
  }
  modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += m;
    }
    a -= rhs.a;
    return *this;
  }
  modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % m;
    return *this;
  }
};

ostream &operator<<(ostream &stream, const modint &data) {
  stream << data.a;
  return stream;
}

ll n;
vector<vector<int>> g;

vector<map<int, modint>> children;

modint dfs(int current, int prev) {
  // 頂点current が黒である組み合わせ
  modint i = 1;
  for (auto c : g[current]) {
    if (c == prev)
      continue;
    modint t = dfs(c, current) + 1;
    children[current][c] = t;
    i *= t;
  }
  return i;
}

vector<modint> dp1;

void dfs2(int current, int parent, modint pValue) {
  // 親ノードの情報マージ
  auto &child = children[current];
  if (parent != -1) {
    child[parent] = pValue + 1;
  }
  modint &ans = dp1[current];
  ans = 1;
  for (auto p : child) {
    ans *= p.second;
  }

  // publish
  auto csize = child.size();
  if (csize <= 0)
    return;
  vector<int> next;
  for (auto p : child) {
    next.push_back(p.first);
  }
  auto b = child.begin();
  auto rb = child.rbegin();
  vector<modint> pos(csize);
  vector<modint> neg(csize);
  pos[0] = b->second;
  neg[csize - 1] = rb->second;
  for (int i = 1; i < csize; i++) {
    b++;
    rb++;
    pos[i] = pos[i - 1] * b->second;
    neg[csize - 1 - i] = neg[csize - i] * rb->second;
  }
  for (int i = 0; i < csize; i++) {
    if (next[i] == parent)
      continue;
    modint p = 1;
    if (i > 0) {
      p *= pos[i - 1];
    }
    if (i < csize - 1) {
      p *= neg[i + 1];
    }
    dfs2(next[i], current, p);
  }
}

int main() {
  cin >> n >> m;
  g.resize(n);
  dp1.resize(n);
  children.resize(n);
  rep(i, n - 1) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  dfs(0, -1);
  dfs2(0, -1, 0);
  rep(i, n) { cout << dp1[i] << endl; }
  return 0;
}