Problem p03181 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define all(cont) cont.begin(), cont.end()
#define pb push_back
#define fi first
#define se second
#define DEBUG(x) cerr << (#x) << ": " << (x) << '\n'

using namespace std;

typedef pair<int, int> pii;
typedef vector<int> vi;
typedef long long ll;
typedef unsigned long long ull;

template <class T> bool uin(T &a, T b) {
  return (a < b ? false : (a = b, true));
}
template <class T> bool uax(T &a, T b) {
  return (a > b ? false : (a = b, true));
}

//~ ifstream f(".in");
//~ ofstream g(".out");

const int NMAX = 1e5 + 5;

int n, MOD;
vector<int> adj[NMAX];
int down[NMAX];
int up[NMAX];

void mul(int &a, int b) { a = (1LL * a * b) % MOD; }

void add(int &a, int b) { a = (a + b) % MOD; }

int prev(const vector<int> &v, int i) { return (i == 0) ? 1 : v[i - 1]; }

int next(const vector<int> &v, int i) {
  return (i == (int)v.size() - 1) ? 1 : v[i + 1];
}

void dfs(int node, int parent, int type) {
  if (type == 0) {
    down[node] = up[node] = 1;
    for (int &x : adj[node]) {
      if (x == parent) {
        continue;
      }
      dfs(x, node, type);
      mul(down[node], down[x] + 1);
    }
    return;
  }
  vector<int> pref_prod(adj[node].size() - 1, 1);
  vector<int> suff_prod(adj[node].size() - 1, 1);
  for (int i = 0, idx = 0; i < (int)adj[node].size(); ++i) {
    int x = adj[node][i];
    if (x != parent) {
      pref_prod[idx] = 1LL * prev(pref_prod, idx) * (down[x] + 1) % MOD;
      ++idx;
    }
  }
  for (int i = adj[node].size() - 1, idx = i - 1; i >= 0; --i) {
    int x = adj[node][i];
    if (x != parent) {
      suff_prod[i] = 1LL * next(suff_prod, i) * (down[x] + 1) % MOD;
      --idx;
    }
  }
  for (int i = 0, idx = 0; i < (int)adj[node].size(); ++i) {
    int x = adj[node][i];
    if (x != parent) {
      add(up[x], (1LL * up[node] * prev(pref_prod, idx) % MOD) *
                     next(suff_prod, idx) % MOD);
      ++idx;
      dfs(x, node, type);
    }
  }
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
#ifdef LOCAL_DEFINE
  freopen(".in", "r", stdin);
#endif

  cin >> n >> MOD;
  for (int i = 1; i <= n - 1; ++i) {
    int x, y;
    cin >> x >> y;
    adj[x].push_back(y);
    adj[y].push_back(x);
  }

  adj[1].push_back(0);
  dfs(1, 0, 0);
  dfs(1, 0, 1);

  for (int i = 1; i <= n; ++i) {
    cout << 1LL * down[i] * up[i] % MOD << '\n';
  }

#ifdef LOCAL_DEFINE
  cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define all(cont) cont.begin(), cont.end()
#define pb push_back
#define fi first
#define se second
#define DEBUG(x) cerr << (#x) << ": " << (x) << '\n'

using namespace std;

typedef pair<int, int> pii;
typedef vector<int> vi;
typedef long long ll;
typedef unsigned long long ull;

template <class T> bool uin(T &a, T b) {
  return (a < b ? false : (a = b, true));
}
template <class T> bool uax(T &a, T b) {
  return (a > b ? false : (a = b, true));
}

//~ ifstream f(".in");
//~ ofstream g(".out");

const int NMAX = 1e5 + 5;

int n, MOD;
vector<int> adj[NMAX];
int down[NMAX];
int up[NMAX];

void mul(int &a, int b) { a = (1LL * a * b) % MOD; }

void add(int &a, int b) { a = (a + b) % MOD; }

int prev(const vector<int> &v, int i) { return (i == 0) ? 1 : v[i - 1]; }

int next(const vector<int> &v, int i) {
  return (i == (int)v.size() - 1) ? 1 : v[i + 1];
}

void dfs(int node, int parent, int type) {
  if (type == 0) {
    down[node] = up[node] = 1;
    for (int &x : adj[node]) {
      if (x == parent) {
        continue;
      }
      dfs(x, node, type);
      mul(down[node], down[x] + 1);
    }
    return;
  }
  vector<int> pref_prod(adj[node].size() - 1, 1);
  vector<int> suff_prod(adj[node].size() - 1, 1);
  for (int i = 0, idx = 0; i < (int)adj[node].size(); ++i) {
    int x = adj[node][i];
    if (x != parent) {
      pref_prod[idx] = 1LL * prev(pref_prod, idx) * (down[x] + 1) % MOD;
      ++idx;
    }
  }
  for (int i = adj[node].size() - 1, idx = i - 1; i >= 0; --i) {
    int x = adj[node][i];
    if (x != parent) {
      suff_prod[idx] = 1LL * next(suff_prod, idx) * (down[x] + 1) % MOD;
      --idx;
    }
  }
  for (int i = 0, idx = 0; i < (int)adj[node].size(); ++i) {
    int x = adj[node][i];
    if (x != parent) {
      add(up[x], (1LL * up[node] * prev(pref_prod, idx) % MOD) *
                     next(suff_prod, idx) % MOD);
      ++idx;
      dfs(x, node, type);
    }
  }
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
#ifdef LOCAL_DEFINE
  freopen(".in", "r", stdin);
#endif

  cin >> n >> MOD;
  for (int i = 1; i <= n - 1; ++i) {
    int x, y;
    cin >> x >> y;
    adj[x].push_back(y);
    adj[y].push_back(x);
  }

  adj[1].push_back(0);
  dfs(1, 0, 0);
  dfs(1, 0, 1);

  for (int i = 1; i <= n; ++i) {
    cout << 1LL * down[i] * up[i] % MOD << '\n';
  }

#ifdef LOCAL_DEFINE
  cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
  return 0;
}