Problem p03499 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>
#include <vector>

using namespace std;

typedef vector<int> vi;
typedef long long ll;
#define pb push_back
#define pf push_front
#define siz(x) ((int)x.size())
#define rep(i, a, n) for (int i = (a); i < (n); ++i)
#define per(i, a, n) for (int i = (n)-1; i >= (a); --i)

inline int read() {
  int x;
  scanf("%d", &x);
  return x;
}

const int N = 1e5 + 5;
const ll mod = 1e9 + 7;

int n;

vi dep[N];
vi g[N];

void dfs0(int u, int h) {
  dep[h].pb(u);
  rep(i, 0, siz(g[u])) {
    int v = g[u][i];
    dfs0(v, h + 1);
  }
}

ll fac[N];

struct st {
  ll x0, x1, x2;
};

typedef deque<st> di;

di d[N];
int id[N];

void merst(di &a, di &b, int &ta, int &tb, int cnt) {
  if (siz(a) == 0 || siz(b) == 0)
    return;
  st x = a.front();
  a.pop_front();
  st y = b.front();
  b.pop_front();
  if (cnt == ta)
    ++ta, x.x0 = (x.x0 + x.x2) % mod, x.x2 = 0;
  if (cnt == tb)
    ++tb, y.x0 = (y.x0 + y.x2) % mod, y.x2 = 0;
  merst(a, b, ta, tb, cnt + 1);
  st c;
  c.x0 = x.x0 * y.x0 % mod;
  c.x1 = (x.x0 * y.x1 % mod + x.x1 * y.x0 % mod) % mod;
  c.x2 = (x.x0 * y.x2 % mod + x.x1 * y.x2 % mod + x.x2 * y.x2 % mod +
          x.x1 * y.x1 % mod + x.x2 * y.x1 % mod + x.x2 * y.x0 % mod) %
         mod;
  if (siz(a) > siz(b))
    a.pf(c);
  else
    b.pf(c);
}

int tag[N];

void dfs(int u) {
  int t = n + 1;
  rep(i, 0, siz(g[u])) {
    int v = g[u][i];
    dfs(v);
    merst(d[t], d[id[v]], tag[t], tag[id[v]], 0);
    if (siz(d[t]) < siz(d[id[v]]))
      t = id[v];
  }
  if (t == n + 1)
    t = u;
  st s;
  s.x0 = s.x1 = 1, s.x2 = 0;
  id[u] = t;
  d[t].pf(s);
  tag[t] = 0;
}

int main() {
  n = read();
  rep(i, 0, n) g[read()].pb(i + 1);
  ++n;
  fac[0] = 1;
  rep(i, 1, n + 1) fac[i] = fac[i - 1] * 2ll % mod;
  dfs0(0, 0);
  dfs(0);
  ll sum = 0;
  di &s = d[id[0]];
  int now = 0;
  while (!s.empty()) {
    ll k = s.front().x1;
    s.pop_front();
    sum += fac[n - siz(dep[now])] * k % mod, sum %= mod, ++now;
  }
  printf("%lld\n", sum);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>
#include <vector>

using namespace std;

typedef vector<int> vi;
typedef long long ll;
#define pb push_back
#define pf push_front
#define siz(x) ((int)x.size())
#define rep(i, a, n) for (int i = (a); i < (n); ++i)
#define per(i, a, n) for (int i = (n)-1; i >= (a); --i)

inline int read() {
  int x;
  scanf("%d", &x);
  return x;
}

const int N = 2e5 + 5;
const ll mod = 1e9 + 7;

int n;

vi dep[N];
vi g[N];

void dfs0(int u, int h) {
  dep[h].pb(u);
  rep(i, 0, siz(g[u])) {
    int v = g[u][i];
    dfs0(v, h + 1);
  }
}

ll fac[N];

struct st {
  ll x0, x1, x2;
};

typedef deque<st> di;

di d[N];
int id[N];

void merst(di &a, di &b, int &ta, int &tb, int cnt) {
  if (siz(a) == 0 || siz(b) == 0)
    return;
  st x = a.front();
  a.pop_front();
  st y = b.front();
  b.pop_front();
  if (cnt == ta)
    ++ta, x.x0 = (x.x0 + x.x2) % mod, x.x2 = 0;
  if (cnt == tb)
    ++tb, y.x0 = (y.x0 + y.x2) % mod, y.x2 = 0;
  merst(a, b, ta, tb, cnt + 1);
  st c;
  c.x0 = x.x0 * y.x0 % mod;
  c.x1 = (x.x0 * y.x1 % mod + x.x1 * y.x0 % mod) % mod;
  c.x2 = (x.x0 * y.x2 % mod + x.x1 * y.x2 % mod + x.x2 * y.x2 % mod +
          x.x1 * y.x1 % mod + x.x2 * y.x1 % mod + x.x2 * y.x0 % mod) %
         mod;
  if (siz(a) > siz(b))
    a.pf(c);
  else
    b.pf(c);
}

int tag[N];

void dfs(int u) {
  int t = n + 1;
  rep(i, 0, siz(g[u])) {
    int v = g[u][i];
    dfs(v);
    merst(d[t], d[id[v]], tag[t], tag[id[v]], 0);
    if (siz(d[t]) < siz(d[id[v]]))
      t = id[v];
  }
  if (t == n + 1)
    t = u;
  st s;
  s.x0 = s.x1 = 1, s.x2 = 0;
  id[u] = t;
  d[t].pf(s);
  tag[t] = 0;
}

int main() {
  n = read();
  rep(i, 0, n) g[read()].pb(i + 1);
  ++n;
  fac[0] = 1;
  rep(i, 1, n + 1) fac[i] = fac[i - 1] * 2ll % mod;
  dfs0(0, 0);
  dfs(0);
  ll sum = 0;
  di &s = d[id[0]];
  int now = 0;
  while (!s.empty()) {
    ll k = s.front().x1;
    s.pop_front();
    sum += fac[n - siz(dep[now])] * k % mod, sum %= mod, ++now;
  }
  printf("%lld\n", sum);
  return 0;
}