Problem p03499 (C++)

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

typedef long long ll;
typedef pair<int, int> pii;
#define f first
#define s second

const int MAX = 100005;
const int LOG = 19;
const int MOD = 1000000007;
vector<int> g[MAX];
vector<int> dep[MAX];

int pow2[MAX];

int add(int a, int b) { return (a + b) % MOD; }
int sub(int a, int b) { return ((ll)a - (ll)b + 2 * (ll)MOD) % MOD; }
int mult(int a, int b) { return ((ll)a * (ll)b) % MOD; }
int sq(int a) { return mult(a, a); }
int exp(int a, int b) {
  if (b == 0) {
    return 1;
  }
  if (b % 2 == 1) {
    return mult(a, sq(exp(a, b / 2)));
  } else {
    return sq(exp(a, b / 2));
  }
}
int inv(int a) { return exp(a, MOD - 2); }
int divi(int a, int b) { return mult(a, inv(b)); }

int in[MAX], d[MAX], p[MAX][LOG];
int tt = 1;
void dfs(int u, int par = 0) {
  p[u][0] = par;
  if (par == 0) {
    d[u] = 1;
  }
  dep[d[u]].push_back(u);
  in[u] = tt++;
  for (int i : g[u]) {
    if (i == par) {
      continue;
    }
    d[i] = d[u] + 1;
    dfs(i, u);
  }
}
void sparse() {
  for (int i = 1; i < LOG; i++) {
    for (int j = 0; j < MAX; j++) {
      p[j][i] = p[p[j][i - 1]][i - 1];
    }
  }
}
int lca(int u, int v) {
  if (d[u] > d[v]) {
    swap(u, v);
  } // u is above v
  for (int i = LOG - 1; ~i; i--) {
    if (d[p[v][i]] >= d[u]) {
      v = p[v][i];
    }
  }
  if (u == v) {
    return u;
  }
  for (int i = LOG - 1; ~i; i--) {
    if (p[u][i] != p[v][i]) {
      u = p[u][i];
      v = p[v][i];
    }
  }
  return p[u][0];
}

bool comp(int u, int v) { return in[u] < in[v]; }

vector<int> t[MAX];
vector<pii> edges;
vector<int> vertices;
void addEdge(int u, int v) {
  t[u].push_back(v);
  t[v].push_back(u);
  edges.push_back({u, v});
}

void reset() {
  for (pii i : edges) {
    t[i.f].clear();
    t[i.s].clear();
  }
  edges.clear();
  vertices.clear();
}

int stk[MAX];
void build(int cur_d) {
  vector<int> v = dep[cur_d];
  for (int i : v) {
    vertices.push_back(i);
  }
  int k = v.size();
  if (k == 0) {
    return;
  }
  int sz = 0;
  sort(v.begin(), v.end(), comp);
  stk[sz++] = v[0];
  for (int i : v) {
    if (i == v[0]) {
      continue;
    }
    int u = lca(i, stk[sz - 1]);
    if (u == stk[sz - 1]) {
      stk[sz++] = i;
      continue;
    }
    while (sz >= 2 && d[stk[sz - 2]] >= d[u]) {
      addEdge(stk[sz - 1], stk[sz - 2]);
      sz--;
    }
    if (stk[sz - 1] != u) {
      addEdge(u, stk[sz - 1]);
      vertices.push_back(u);
      stk[sz - 1] = u;
    }
    stk[sz++] = i;
  }
  for (int i = 1; i < sz; i++) {
    addEdge(stk[i], stk[i - 1]);
  }
}

int sze[MAX];
pii val[MAX]; // succ, fail

void dfs1(int u, int p, int dep) {
  if (d[u] >= dep) {
    return;
  }
  int prodf = 1;
  int sumf = 0;
  for (int i : t[u]) {
    if (i == p) {
      continue;
    }
    dfs1(i, u, dep);
    sze[u] += sze[i];
    prodf = mult(prodf, val[i].s);
    sumf = add(sumf, divi(val[i].f, val[i].s));
  }
  val[u].f = mult(prodf, sumf);
  val[u].s = sub(pow2[sze[u]], val[u].f);
}

int ans = 0;
void process(int n, int cur_d) {
  for (int i : dep[cur_d]) {
    // cout << "setting sze of " << i << " to " << 1 << endl;
    sze[i] = 1;
    val[i] = {1, 1};
  }
  build(cur_d);
  int root = -1;
  int mini = MAX;
  for (int i : vertices) {
    if (d[i] < mini) {
      mini = d[i];
      root = i;
    }
  }
  if (root == -1) {
    return;
  }
  dfs1(root, -1, cur_d);
  ans = add(ans, mult(pow2[n + 1 - sze[root]], val[root].f));
  for (int i : vertices) {
    sze[i] = 0;
    val[i] = {0, 0};
  }
  reset();
}

int main() {
  // freopen("a.in", "r", stdin);
  pow2[0] = 1;
  for (int i = 1; i < MAX; i++) {
    pow2[i] = (pow2[i - 1] * 2) % MOD;
  }
  int n;
  scanf("%d", &n);
  for (int i = 2; i <= n + 1; i++) {
    int p;
    scanf("%d", &p);
    p++;
    g[p].push_back(i);
  }
  dfs(1);
  sparse();
  for (int i = 1; i <= n + 1; i++) {
    process(n, i);
  }
  printf("%d\n", ans);
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
#define f first
#define s second

const int MAX = 200005;
const int LOG = 19;
const int MOD = 1000000007;
vector<int> g[MAX];
vector<int> dep[MAX];

int pow2[MAX];

int add(int a, int b) { return (a + b) % MOD; }
int sub(int a, int b) { return ((ll)a - (ll)b + 2 * (ll)MOD) % MOD; }
int mult(int a, int b) { return ((ll)a * (ll)b) % MOD; }
int sq(int a) { return mult(a, a); }
int exp(int a, int b) {
  if (b == 0) {
    return 1;
  }
  if (b % 2 == 1) {
    return mult(a, sq(exp(a, b / 2)));
  } else {
    return sq(exp(a, b / 2));
  }
}
int inv(int a) { return exp(a, MOD - 2); }
int divi(int a, int b) { return mult(a, inv(b)); }

int in[MAX], d[MAX], p[MAX][LOG];
int tt = 1;
void dfs(int u, int par = 0) {
  p[u][0] = par;
  if (par == 0) {
    d[u] = 1;
  }
  dep[d[u]].push_back(u);
  in[u] = tt++;
  for (int i : g[u]) {
    if (i == par) {
      continue;
    }
    d[i] = d[u] + 1;
    dfs(i, u);
  }
}
void sparse() {
  for (int i = 1; i < LOG; i++) {
    for (int j = 0; j < MAX; j++) {
      p[j][i] = p[p[j][i - 1]][i - 1];
    }
  }
}
int lca(int u, int v) {
  if (d[u] > d[v]) {
    swap(u, v);
  } // u is above v
  for (int i = LOG - 1; ~i; i--) {
    if (d[p[v][i]] >= d[u]) {
      v = p[v][i];
    }
  }
  if (u == v) {
    return u;
  }
  for (int i = LOG - 1; ~i; i--) {
    if (p[u][i] != p[v][i]) {
      u = p[u][i];
      v = p[v][i];
    }
  }
  return p[u][0];
}

bool comp(int u, int v) { return in[u] < in[v]; }

vector<int> t[MAX];
vector<pii> edges;
vector<int> vertices;
void addEdge(int u, int v) {
  t[u].push_back(v);
  t[v].push_back(u);
  edges.push_back({u, v});
}

void reset() {
  for (pii i : edges) {
    t[i.f].clear();
    t[i.s].clear();
  }
  edges.clear();
  vertices.clear();
}

int stk[MAX];
void build(int cur_d) {
  vector<int> v = dep[cur_d];
  for (int i : v) {
    vertices.push_back(i);
  }
  int k = v.size();
  if (k == 0) {
    return;
  }
  int sz = 0;
  sort(v.begin(), v.end(), comp);
  stk[sz++] = v[0];
  for (int i : v) {
    if (i == v[0]) {
      continue;
    }
    int u = lca(i, stk[sz - 1]);
    if (u == stk[sz - 1]) {
      stk[sz++] = i;
      continue;
    }
    while (sz >= 2 && d[stk[sz - 2]] >= d[u]) {
      addEdge(stk[sz - 1], stk[sz - 2]);
      sz--;
    }
    if (stk[sz - 1] != u) {
      addEdge(u, stk[sz - 1]);
      vertices.push_back(u);
      stk[sz - 1] = u;
    }
    stk[sz++] = i;
  }
  for (int i = 1; i < sz; i++) {
    addEdge(stk[i], stk[i - 1]);
  }
}

int sze[MAX];
pii val[MAX]; // succ, fail

void dfs1(int u, int p, int dep) {
  if (d[u] >= dep) {
    return;
  }
  int prodf = 1;
  int sumf = 0;
  for (int i : t[u]) {
    if (i == p) {
      continue;
    }
    dfs1(i, u, dep);
    sze[u] += sze[i];
    prodf = mult(prodf, val[i].s);
    sumf = add(sumf, divi(val[i].f, val[i].s));
  }
  val[u].f = mult(prodf, sumf);
  val[u].s = sub(pow2[sze[u]], val[u].f);
}

int ans = 0;
void process(int n, int cur_d) {
  for (int i : dep[cur_d]) {
    // cout << "setting sze of " << i << " to " << 1 << endl;
    sze[i] = 1;
    val[i] = {1, 1};
  }
  build(cur_d);
  int root = -1;
  int mini = MAX;
  for (int i : vertices) {
    if (d[i] < mini) {
      mini = d[i];
      root = i;
    }
  }
  if (root == -1) {
    return;
  }
  dfs1(root, -1, cur_d);
  ans = add(ans, mult(pow2[n + 1 - sze[root]], val[root].f));
  for (int i : vertices) {
    sze[i] = 0;
    val[i] = {0, 0};
  }
  reset();
}

int main() {
  // freopen("a.in", "r", stdin);
  pow2[0] = 1;
  for (int i = 1; i < MAX; i++) {
    pow2[i] = (pow2[i - 1] * 2) % MOD;
  }
  int n;
  scanf("%d", &n);
  for (int i = 2; i <= n + 1; i++) {
    int p;
    scanf("%d", &p);
    p++;
    g[p].push_back(i);
  }
  dfs(1);
  sparse();
  for (int i = 1; i <= n + 1; i++) {
    process(n, i);
  }
  printf("%d\n", ans);
}