Problem p03499 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
#define mp make_pair
#define pb push_back
#define X first
#define Y second
#define rg register
#define il inline
#define lch(x) ((x) << 1)
#define rch(x) ((x) << 1 ^ 1)
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define rep0(i, n) for (register int i = 0; i < (n); ++i)
#define per0(i, n) for (register int i = (n)-1; i >= 0; --i)
#define rep(i, st, ed) for (register int i = (st); i <= (ed); ++i)
#define per(i, ed, st) for (register int i = (ed); i >= (st); --i)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef double dbl;
typedef long double ldb;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
template <typename T> il T qmin(const T &a, const T &b) {
  return a < b ? a : b;
}
template <typename T> il T qmax(const T &a, const T &b) {
  return a > b ? a : b;
}
template <typename T> il void getmin(T &a, const T &b) {
  if (a > b)
    a = b;
}
template <typename T> il void getmax(T &a, const T &b) {
  if (a < b)
    a = b;
}
il void fileio(string s) {
  freopen((s + ".in").c_str(), "r", stdin);
  freopen((s + ".out").c_str(), "w", stdout);
}

const int inf = (int)1e9 + 7;
const ll linf = (ll)1e17 + 7;
const int N = 1e5 + 7;
const int mod = inf;

int v[N], nxt[N];
int head[N], fst[N], par[N], dep[N], n;
int tot[N], pw2[N];

struct dat {
  int a, b, c;
  il dat(const int &x = 1, const int &y = 0, const int &z = 0)
      : a(x), b(y), c(z) {}
  il void operator+=(const dat &y) {
    ll cnt0 = y.a + y.c, cnt1 = y.b;
    c = ((cnt0 + cnt1) * c + cnt1 * b) % mod;
    b = (cnt0 * b + cnt1 * a) % mod;
    a = (cnt0 * a) % mod;
  }
};
dat val[N];
int tp[N], succ[N], cnt;

il int newval(const int &u, const dat &d) {
  ++cnt;
  val[cnt] = d;
  tp[cnt] = u;
  succ[cnt] = 0;
  return cnt;
}

il void merge(int &u, const int &v, const int &cur) {
  if (!v)
    return;
  if (!u) {
    u = v;
    return;
  }
  if (tp[u] != cur) {
    val[u].a += val[u].c;
    if (val[u].a >= mod)
      val[u].a -= mod;
    val[u].c = 0;
    tp[u] = cur;
  }
  val[u] += val[v];
  merge(succ[u], succ[v], cur);
}

il void dfs(const int &u) {
  dep[u] = (u ? dep[par[u]] + 1 : 0);
  ++tot[dep[u]];
  fst[u] = newval(u, dat(1, 1, 0));
  for (int e = head[u]; e; e = nxt[e]) {
    dfs(v[e]);
    merge(succ[fst[u]], fst[v[e]], u);
  }
}

int main() {
  //	fileio("test");
  scanf("%d", &n);
  rep(i, 1, n) {
    scanf("%d", par + i);
    v[i] = i, nxt[i] = head[par[i]], head[par[i]] = i;
  }
  dfs(0);
  pw2[0] = 1;
  rep(i, 1, n + 1) {
    pw2[i] = pw2[i - 1] << 1;
    if (pw2[i] >= mod)
      pw2[i] -= mod;
  }
  ll res = 0;
  for (int i = fst[0], cur = 0; i; i = succ[i], ++cur) {
    res += 1ll * val[i].b * pw2[n + 1 - tot[cur]] % mod;
  }
  printf("%d\n", res % mod);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
#define mp make_pair
#define pb push_back
#define X first
#define Y second
#define rg register
#define il inline
#define lch(x) ((x) << 1)
#define rch(x) ((x) << 1 ^ 1)
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define rep0(i, n) for (register int i = 0; i < (n); ++i)
#define per0(i, n) for (register int i = (n)-1; i >= 0; --i)
#define rep(i, st, ed) for (register int i = (st); i <= (ed); ++i)
#define per(i, ed, st) for (register int i = (ed); i >= (st); --i)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef double dbl;
typedef long double ldb;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
template <typename T> il T qmin(const T &a, const T &b) {
  return a < b ? a : b;
}
template <typename T> il T qmax(const T &a, const T &b) {
  return a > b ? a : b;
}
template <typename T> il void getmin(T &a, const T &b) {
  if (a > b)
    a = b;
}
template <typename T> il void getmax(T &a, const T &b) {
  if (a < b)
    a = b;
}
il void fileio(string s) {
  freopen((s + ".in").c_str(), "r", stdin);
  freopen((s + ".out").c_str(), "w", stdout);
}

const int inf = (int)1e9 + 7;
const ll linf = (ll)1e17 + 7;
const int N = 2e5 + 7;
const int mod = inf;

int v[N], nxt[N];
int head[N], fst[N], par[N], dep[N], n;
int tot[N], pw2[N];

struct dat {
  int a, b, c;
  il dat(const int &x = 1, const int &y = 0, const int &z = 0)
      : a(x), b(y), c(z) {}
  il void operator+=(const dat &y) {
    ll cnt0 = y.a + y.c, cnt1 = y.b;
    c = ((cnt0 + cnt1) * c + cnt1 * b) % mod;
    b = (cnt0 * b + cnt1 * a) % mod;
    a = (cnt0 * a) % mod;
  }
};
dat val[N];
int tp[N], succ[N], cnt;

il int newval(const int &u, const dat &d) {
  ++cnt;
  val[cnt] = d;
  tp[cnt] = u;
  succ[cnt] = 0;
  return cnt;
}

il void merge(int &u, const int &v, const int &cur) {
  if (!v)
    return;
  if (!u) {
    u = v;
    return;
  }
  if (tp[u] != cur) {
    val[u].a += val[u].c;
    if (val[u].a >= mod)
      val[u].a -= mod;
    val[u].c = 0;
    tp[u] = cur;
  }
  val[u] += val[v];
  merge(succ[u], succ[v], cur);
}

il void dfs(const int &u) {
  dep[u] = (u ? dep[par[u]] + 1 : 0);
  ++tot[dep[u]];
  fst[u] = newval(u, dat(1, 1, 0));
  for (int e = head[u]; e; e = nxt[e]) {
    dfs(v[e]);
    merge(succ[fst[u]], fst[v[e]], u);
  }
}

int main() {
  //	fileio("test");
  scanf("%d", &n);
  rep(i, 1, n) {
    scanf("%d", par + i);
    v[i] = i, nxt[i] = head[par[i]], head[par[i]] = i;
  }
  dfs(0);
  pw2[0] = 1;
  rep(i, 1, n + 1) {
    pw2[i] = pw2[i - 1] << 1;
    if (pw2[i] >= mod)
      pw2[i] -= mod;
  }
  ll res = 0;
  for (int i = fst[0], cur = 0; i; i = succ[i], ++cur) {
    res += 1ll * val[i].b * pw2[n + 1 - tot[cur]] % mod;
  }
  printf("%d\n", res % mod);
  return 0;
}