Problem p03499 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define N 100005
#define P 1000000007
using namespace std;
int i, j, k, l, s, n, m, S[N], f[N][3], F[5], ans, fa[N], si[N], dis[N], st[N],
    q[N], r, FA[N], tot, id[N], vis[N];
struct node {
  int tot, last[N], to[2 * N], Next[2 * N];
  inline void add(int x, int y) {
    Next[++tot] = last[x];
    last[x] = tot;
    to[tot] = y;
  }
} A, B;
inline void dfs(int x, int y) {
  if (y == -1)
    y = x;
  FA[x] = y;
  st[x] = ++tot;
  int gt = 0, gtw = 0;
  for (int i = A.last[x]; i; i = A.Next[i])
    if (si[A.to[i]] > gt)
      gt = si[A.to[i]], gtw = A.to[i];
  if (!gtw)
    return;
  dfs(gtw, y);
  for (int i = A.last[x]; i; i = A.Next[i])
    if (A.to[i] != gtw)
      dfs(A.to[i], -1);
}
inline bool cmp1(int x, int y) { return st[x] < st[y]; }
inline bool cmp(int x, int y) { return dis[x] > dis[y]; }
inline int quick(int x, int y) {
  int s = 1;
  while (y) {
    if (y & 1)
      s = 1ll * s * x % P;
    x = 1ll * x * x % P;
    y >>= 1;
  }
  return s;
}
inline int get(int x, int y) {
  while (FA[x] != FA[y]) {
    if (dis[FA[x]] > dis[FA[y]])
      x = fa[FA[x]];
    else
      y = fa[FA[y]];
  }
  if (dis[x] > dis[y])
    return y;
  return x;
}
inline void work(int x, int y) {
  if (x == y) {
    (ans += quick(2, n + 1 - (y - x + 1))) %= P;
    return;
  }
  int r = 0;
  sort(id + x, id + y + 1, cmp1);
  for (int i = x; i <= y; i++)
    f[id[i]][1] = f[id[i]][0] = 1;
  int stack = 0;
  for (int i = x + 1; i <= y; i++) {
    int lca = get(id[i - 1], id[i]);
    if (!vis[lca])
      vis[q[++r] = lca] = 1;
    for (; stack; stack--) {
      if (dis[S[stack]] <= dis[lca])
        break;
      if (dis[S[stack - 1]] > dis[lca] && stack > 1)
        B.add(S[stack - 1], S[stack]);
      else
        B.add(lca, S[stack]);
    }
    if (S[stack] != lca || (!stack))
      S[++stack] = lca;
  }
  while (stack > 1)
    B.add(S[stack - 1], S[stack]), stack--;
  for (int i = x + 1; i < y; i++) {
    int L = get(id[i - 1], id[i]), R = get(id[i], id[i + 1]);
    if (dis[L] > dis[R])
      B.add(L, id[i]);
    else
      B.add(R, id[i]);
  }
  B.add(get(id[x], id[x + 1]), id[x]);
  B.add(get(id[y], id[y - 1]), id[y]);
  sort(q + 1, q + 1 + r, cmp);
  for (int i = 1; i <= r; i++) {
    F[0] = 1;
    F[1] = F[2] = 0;
    for (int j = B.last[q[i]]; j; j = B.Next[j]) {
      F[2] = (1ll * F[2] * (f[B.to[j]][0] + f[B.to[j]][1]) +
              1ll * F[1] * f[B.to[j]][1]) %
             P;
      F[1] = (1ll * F[1] * f[B.to[j]][0] + 1ll * F[0] * f[B.to[j]][1]) % P;
      F[0] = 1ll * F[0] * f[B.to[j]][0] % P;
    }
    f[q[i]][0] = (F[0] + F[2]) % P;
    f[q[i]][1] = F[1];
  }
  (ans += 1ll * f[q[r]][1] * quick(2, n + 1 - (y - x + 1)) % P) %= P;
  for (int i = 1; i <= r; i++)
    B.last[q[i]] = vis[q[i]] = 0;
  B.tot = 0;
}
int main() {
  scanf("%d", &n);
  for (i = 1; i <= n; i++)
    scanf("%d", &fa[i]), A.add(fa[i], i);
  for (i = n; i; i--)
    si[i]++, si[fa[i]] += si[i];
  dis[0] = 1;
  for (i = 1; i <= n; i++)
    dis[i] = dis[fa[i]] + 1;
  dfs(0, -1);
  for (i = 1; i <= n; i++)
    id[i] = i;
  sort(id + 1, id + 1 + n, cmp);
  ans = quick(2, n);
  for (i = 1; i <= n; i = j) {
    j = i;
    while (dis[id[j]] == dis[id[i]])
      j++;
    work(i, j - 1);
  }
  printf("%d\n", ans);
}

Fixed submission:
#include <bits/stdc++.h>
#define N 200005
#define P 1000000007
using namespace std;
int i, j, k, l, s, n, m, S[N], f[N][3], F[5], ans, fa[N], si[N], dis[N], st[N],
    q[N], r, FA[N], tot, id[N], vis[N];
struct node {
  int tot, last[N], to[2 * N], Next[2 * N];
  inline void add(int x, int y) {
    Next[++tot] = last[x];
    last[x] = tot;
    to[tot] = y;
  }
} A, B;
inline void dfs(int x, int y) {
  if (y == -1)
    y = x;
  FA[x] = y;
  st[x] = ++tot;
  int gt = 0, gtw = 0;
  for (int i = A.last[x]; i; i = A.Next[i])
    if (si[A.to[i]] > gt)
      gt = si[A.to[i]], gtw = A.to[i];
  if (!gtw)
    return;
  dfs(gtw, y);
  for (int i = A.last[x]; i; i = A.Next[i])
    if (A.to[i] != gtw)
      dfs(A.to[i], -1);
}
inline bool cmp1(int x, int y) { return st[x] < st[y]; }
inline bool cmp(int x, int y) { return dis[x] > dis[y]; }
inline int quick(int x, int y) {
  int s = 1;
  while (y) {
    if (y & 1)
      s = 1ll * s * x % P;
    x = 1ll * x * x % P;
    y >>= 1;
  }
  return s;
}
inline int get(int x, int y) {
  while (FA[x] != FA[y]) {
    if (dis[FA[x]] > dis[FA[y]])
      x = fa[FA[x]];
    else
      y = fa[FA[y]];
  }
  if (dis[x] > dis[y])
    return y;
  return x;
}
inline void work(int x, int y) {
  if (x == y) {
    (ans += quick(2, n + 1 - (y - x + 1))) %= P;
    return;
  }
  int r = 0;
  sort(id + x, id + y + 1, cmp1);
  for (int i = x; i <= y; i++)
    f[id[i]][1] = f[id[i]][0] = 1;
  int stack = 0;
  for (int i = x + 1; i <= y; i++) {
    int lca = get(id[i - 1], id[i]);
    if (!vis[lca])
      vis[q[++r] = lca] = 1;
    for (; stack; stack--) {
      if (dis[S[stack]] <= dis[lca])
        break;
      if (dis[S[stack - 1]] > dis[lca] && stack > 1)
        B.add(S[stack - 1], S[stack]);
      else
        B.add(lca, S[stack]);
    }
    if (S[stack] != lca || (!stack))
      S[++stack] = lca;
  }
  while (stack > 1)
    B.add(S[stack - 1], S[stack]), stack--;
  for (int i = x + 1; i < y; i++) {
    int L = get(id[i - 1], id[i]), R = get(id[i], id[i + 1]);
    if (dis[L] > dis[R])
      B.add(L, id[i]);
    else
      B.add(R, id[i]);
  }
  B.add(get(id[x], id[x + 1]), id[x]);
  B.add(get(id[y], id[y - 1]), id[y]);
  sort(q + 1, q + 1 + r, cmp);
  for (int i = 1; i <= r; i++) {
    F[0] = 1;
    F[1] = F[2] = 0;
    for (int j = B.last[q[i]]; j; j = B.Next[j]) {
      F[2] = (1ll * F[2] * (f[B.to[j]][0] + f[B.to[j]][1]) +
              1ll * F[1] * f[B.to[j]][1]) %
             P;
      F[1] = (1ll * F[1] * f[B.to[j]][0] + 1ll * F[0] * f[B.to[j]][1]) % P;
      F[0] = 1ll * F[0] * f[B.to[j]][0] % P;
    }
    f[q[i]][0] = (F[0] + F[2]) % P;
    f[q[i]][1] = F[1];
  }
  (ans += 1ll * f[q[r]][1] * quick(2, n + 1 - (y - x + 1)) % P) %= P;
  for (int i = 1; i <= r; i++)
    B.last[q[i]] = vis[q[i]] = 0;
  B.tot = 0;
}
int main() {
  scanf("%d", &n);
  for (i = 1; i <= n; i++)
    scanf("%d", &fa[i]), A.add(fa[i], i);
  for (i = n; i; i--)
    si[i]++, si[fa[i]] += si[i];
  dis[0] = 1;
  for (i = 1; i <= n; i++)
    dis[i] = dis[fa[i]] + 1;
  dfs(0, -1);
  for (i = 1; i <= n; i++)
    id[i] = i;
  sort(id + 1, id + 1 + n, cmp);
  ans = quick(2, n);
  for (i = 1; i <= n; i = j) {
    j = i;
    while (dis[id[j]] == dis[id[i]])
      j++;
    work(i, j - 1);
  }
  printf("%d\n", ans);
}