Problem p03181 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
// #define P pair<ll,ll>
#define FOR(I, A, B) for (ll I = ll(A); I < ll(B); ++I)
#define FORR(I, A, B) for (ll I = ll((B)-1); I >= ll(A); --I)
#define TO(x, t, f) ((x) ? (t) : (f))
#define SORT(x) (sort(x.begin(), x.end())) // 0 2 2 3 4 5 8 9
#define POSL(x, v)                                                             \
  (lower_bound(x.begin(), x.end(), v) - x.begin()) // xi>=v  x is sorted
#define POSU(x, v)                                                             \
  (upper_bound(x.begin(), x.end(), v) - x.begin()) // xi>v  x is sorted
#define NUM(x, v) (POSU(x, v) - POSL(x, v))        // x is sorted
#define REV(x) (reverse(x.begin(), x.end()))       // reverse
ll gcd(ll a, ll b) {
  if (a % b == 0)
    return b;
  return gcd(b, a % b);
}
ll lcm(ll a, ll b) {
  ll c = gcd(a, b);
  return ((a / c) * (b / c) * c);
}
#define NEXTP(x) next_permutation(x.begin(), x.end())
const ll INF = ll(1e16) + ll(7);
const ll MOD = 1000000007LL;
#define out(a) cout << fixed << setprecision((a))

template <typename T> class func {
public: // 0-index
  vector<T> datf, datb;
  T M, initial;
  int n;
  T f(T a, T b) { return (a * b) % M; }
  void final_updete(int j, T x) {
    for (int i = j; i < n; i++)
      (datf[i] *= x) %= M;
    for (int i = j; i >= 0; i--)
      (datb[i] *= x) %= M;
  }
  void init(int n_, T initial_, T M_) {
    M = M_;
    n = n_;
    initial = initial_;
    datf.resize(n, initial);
    datb.resize(n, initial);
  }
  void update(int i, T x) {
    datb[i] = x;
    datf[i] = x;
  }
  void calc() {
    for (int i = 1; i < n; i++)
      datf[i] = f(datf[i], datf[i - 1]);
    for (int i = n - 2; i >= 0; i--)
      datb[i] = f(datb[i], datb[i + 1]);
  }
  T get_b(int i) {
    if (i >= n || i < 0)
      return initial;
    return datb[i];
  }
  T get_f(int i) {
    if (i >= n || i < 0)
      return initial;
    return datf[i];
  }
  T get_except(int i) { return f(get_f(i - 1), get_b(i + 1)); }
  T get_all() { return datb[0]; }
};

vector<int> leaf(const vector<int> &u, const vector<int> &v) {
  int N = u.size() + 1;
  vector<int> G(N, 0), res;
  for (int i = 0; i < N - 1; i++) {
    G[u[i]]++;
    G[v[i]]++;
  }
  for (int i = 0; i < N; i++) {
    if (G[i] == 1) {
      res.push_back(i);
    }
  }
  return res;
}

vector<pair<int, int>> leaf_to_root(const vector<int> &u, const vector<int> &v,
                                    const int root) {
  // return <parent,child>
  int yet = 1000000000;
  vector<int> d(u.size() + 1, yet);
  vector<pair<int, int>> res;
  queue<int> Q;
  Q.push(root);
  d[root] = 0;
  vector<vector<int>> G(u.size() + 1);
  for (int i = 0; i < u.size(); i++) {
    G[u[i]].push_back(v[i]);
    G[v[i]].push_back(u[i]);
  }
  while (Q.size()) {
    int now = Q.front();
    Q.pop();
    for (auto nex : G[now]) {
      if (d[nex] != yet)
        continue;
      d[nex] = d[now] + 1;
      Q.push(nex);
      res.push_back(make_pair(now, nex));
    }
  }
  reverse(res.begin(), res.end());
  return res;
}

int main() {

  int N, M;
  cin >> N >> M;
  vector<int> x(N - 1), y(N - 1);
  FOR(i, 0, N - 1) cin >> x[i] >> y[i];
  FOR(i, 0, N - 1) x[i]--, y[i]--;

  vector<vector<int>> G(N);
  for (int i = 0; i < N - 1; i++) {
    G[x[i]].push_back(y[i]);
    G[y[i]].push_back(x[i]);
  }
  vector<map<int, int>> ma(N);
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < G[i].size(); j++) {
      ma[i][G[i][j]] = j;
    }
  }
  vector<ll> val(N, 1);

  vector<func<ll>> dp(N);
  for (int i = 0; i < N; i++) {
    dp[i].init(G[i].size(), 1, M);
  }

  auto route = leaf_to_root(x, y, 0);
  for (auto a : route) {
    int p = a.first;
    int c = a.second;
    (val[p] *= val[c] + 1LL) %= M;
    dp[p].update(ma[p][c], (val[c] + 1LL) % M);
  }

  for (int i = 0; i < N; i++)
    dp[i].calc();

  reverse(route.begin(), route.end());
  for (auto a : route) {
    int c = a.second;
    int p = a.first;
    ll v = dp[p].get_except(ma[p][c]);
    dp[c].final_updete(ma[c][p], (v + 1LL) % M);
  }

  for (int i = 0; i < N; i++) {
    cout << dp[i].get_all() << endl;
  }
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
// #define P pair<ll,ll>
#define FOR(I, A, B) for (ll I = ll(A); I < ll(B); ++I)
#define FORR(I, A, B) for (ll I = ll((B)-1); I >= ll(A); --I)
#define TO(x, t, f) ((x) ? (t) : (f))
#define SORT(x) (sort(x.begin(), x.end())) // 0 2 2 3 4 5 8 9
#define POSL(x, v)                                                             \
  (lower_bound(x.begin(), x.end(), v) - x.begin()) // xi>=v  x is sorted
#define POSU(x, v)                                                             \
  (upper_bound(x.begin(), x.end(), v) - x.begin()) // xi>v  x is sorted
#define NUM(x, v) (POSU(x, v) - POSL(x, v))        // x is sorted
#define REV(x) (reverse(x.begin(), x.end()))       // reverse
ll gcd(ll a, ll b) {
  if (a % b == 0)
    return b;
  return gcd(b, a % b);
}
ll lcm(ll a, ll b) {
  ll c = gcd(a, b);
  return ((a / c) * (b / c) * c);
}
#define NEXTP(x) next_permutation(x.begin(), x.end())
const ll INF = ll(1e16) + ll(7);
const ll MOD = 1000000007LL;
#define out(a) cout << fixed << setprecision((a))

template <typename T> class func {
public: // 0-index
  vector<T> datf, datb;
  T M, initial;
  int n;
  T f(T a, T b) { return (a * b) % M; }
  void final_updete(int j, T x) {
    for (int i = j; i < n; i++)
      (datf[i] *= x) %= M;
    for (int i = j; i >= 0; i--)
      (datb[i] *= x) %= M;
  }
  void init(int n_, T initial_, T M_) {
    M = M_;
    n = n_;
    initial = initial_;
    datf.resize(n, initial);
    datb.resize(n, initial);
  }
  void update(int i, T x) {
    datb[i] = x;
    datf[i] = x;
  }
  void calc() {
    for (int i = 1; i < n; i++)
      datf[i] = f(datf[i], datf[i - 1]);
    for (int i = n - 2; i >= 0; i--)
      datb[i] = f(datb[i], datb[i + 1]);
  }
  T get_b(int i) {
    if (i >= n || i < 0)
      return initial;
    return datb[i];
  }
  T get_f(int i) {
    if (i >= n || i < 0)
      return initial;
    return datf[i];
  }
  T get_except(int i) { return f(get_f(i - 1), get_b(i + 1)); }
  T get_all() { return datb[0]; }
};

vector<int> leaf(const vector<int> &u, const vector<int> &v) {
  int N = u.size() + 1;
  vector<int> G(N, 0), res;
  for (int i = 0; i < N - 1; i++) {
    G[u[i]]++;
    G[v[i]]++;
  }
  for (int i = 0; i < N; i++) {
    if (G[i] == 1) {
      res.push_back(i);
    }
  }
  return res;
}

vector<pair<int, int>> leaf_to_root(const vector<int> &u, const vector<int> &v,
                                    const int root) {
  // return <parent,child>
  int yet = 1000000000;
  vector<int> d(u.size() + 1, yet);
  vector<pair<int, int>> res;
  queue<int> Q;
  Q.push(root);
  d[root] = 0;
  vector<vector<int>> G(u.size() + 1);
  for (int i = 0; i < u.size(); i++) {
    G[u[i]].push_back(v[i]);
    G[v[i]].push_back(u[i]);
  }
  while (Q.size()) {
    int now = Q.front();
    Q.pop();
    for (auto nex : G[now]) {
      if (d[nex] != yet)
        continue;
      d[nex] = d[now] + 1;
      Q.push(nex);
      res.push_back(make_pair(now, nex));
    }
  }
  reverse(res.begin(), res.end());
  return res;
}

int main() {

  int N, M;
  cin >> N >> M;
  vector<int> x(N - 1), y(N - 1);
  FOR(i, 0, N - 1) cin >> x[i] >> y[i];
  FOR(i, 0, N - 1) x[i]--, y[i]--;

  if (N == 1) {
    cout << 1 << endl;
    return 0;
  }

  vector<vector<int>> G(N);
  for (int i = 0; i < N - 1; i++) {
    G[x[i]].push_back(y[i]);
    G[y[i]].push_back(x[i]);
  }
  vector<map<int, int>> ma(N);
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < G[i].size(); j++) {
      ma[i][G[i][j]] = j;
    }
  }
  vector<ll> val(N, 1);

  vector<func<ll>> dp(N);
  for (int i = 0; i < N; i++) {
    dp[i].init(G[i].size(), 1, M);
  }

  auto route = leaf_to_root(x, y, 0);
  for (auto a : route) {
    int p = a.first;
    int c = a.second;
    (val[p] *= val[c] + 1LL) %= M;
    dp[p].update(ma[p][c], (val[c] + 1LL) % M);
  }

  for (int i = 0; i < N; i++)
    dp[i].calc();

  reverse(route.begin(), route.end());
  for (auto a : route) {
    int c = a.second;
    int p = a.first;
    ll v = dp[p].get_except(ma[p][c]);
    dp[c].final_updete(ma[c][p], (v + 1LL) % M);
  }

  for (int i = 0; i < N; i++) {
    cout << dp[i].get_all() << endl;
  }
}