Problem p03499 (C++)

Buggy submission (status: Runtime Error):
// This amazing code is by Eric Sunli Chen.
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>
using namespace std;
template <typename T> bool get_int(T &x) {
  char t = getchar();
  bool neg = false;
  x = 0;
  for (; (t > '9' || t < '0') && t != '-' && t != EOF; t = getchar())
    ;
  if (t == '-')
    neg = true, t = getchar();
  if (t == EOF)
    return false;
  for (; t <= '9' && t >= '0'; t = getchar())
    x = x * 10 + t - '0';
  if (neg)
    x = -x;
  return true;
}
template <typename T> void print_int(T x) {
  if (x < 0)
    putchar('-'), x = -x;
  short a[20] = {}, sz = 0;
  while (x > 0)
    a[sz++] = x % 10, x /= 10;
  if (sz == 0)
    putchar('0');
  for (int i = sz - 1; i >= 0; i--)
    putchar('0' + a[i]);
}
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define get1(a) get_int(a)
#define get2(a, b) (get1(a) && get1(b))
#define get3(a, b, c) (get1(a) && get2(b, c))
#define printendl(a) print_int(a), puts("")
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> pii;
const int inf = 0x3f3f3f3f;
const LL Linf = 1ll << 61;
const double pi = acos(-1.0);

const int mod = 1e9 + 7;
struct sparse_table {
  int lg[100111], n;
  pii v[20][100111];
  void construct(int n, int *a) {
    this->n = n;
    for (int i = 2; i <= n; i++)
      lg[i] = lg[i >> 1] + 1;
    for (int i = 1; i <= n; i++)
      v[0][i] = mp(a[i], i);
    for (int i = 1; i < 20; i++)
      for (int j = 1; j <= n; j++) {
        int nxt = j + (1 << i - 1);
        if (nxt > n)
          v[i][j] = v[i - 1][j];
        else
          v[i][j] = min(v[i - 1][j], v[i - 1][nxt]);
      }
  }
  pii query(int l, int r) {
    if (l > r)
      return mp(-1, -1);
    int len = lg[r - l + 1];
    return min(v[len][l], v[len][r - (1 << len) + 1]);
  }
} thor;
vector<int> g[200111], vs[200111];
int n, f[200111][20], dep[200111], pw2[200111], pre[200111], suf[200111],
    a[200111];

void dfs(int x) {
  for (auto v : g[x])
    dfs(v);
  vs[dep[x]].pb(x);
}
int getlca(int u, int v) {
  if (dep[u] < dep[v])
    swap(u, v);
  for (int i = 19; i >= 0; i--)
    if (dep[u] - dep[v] >> i)
      u = f[u][i];
  if (u == v)
    return u;
  for (int i = 19; i >= 0; i--)
    if (f[u][i] != f[v][i]) {
      u = f[u][i];
      v = f[v][i];
    }
  return f[u][0];
}

pii solve(int l, int r) {
  if (l == r)
    return mp(1, 1);
  int mxv = thor.query(l + 1, r).ff, curl = l;
  vector<pii> q;
  q.pb(mp(0, 0));
  while (true) {
    pii now = thor.query(curl + 1, r);
    if (now.ff != mxv) {
      q.pb(solve(curl, r));
      break;
    }
    q.pb(solve(curl, now.ss - 1));
    curl = now.ss;
  }
  int sz = (int)q.size() - 1;
  pre[0] = suf[sz + 1] = 1;
  for (int i = 1; i <= sz; i++)
    pre[i] = 1ll * pre[i - 1] * q[i].ss % mod;
  for (int i = sz; i >= 1; i--)
    suf[i] = 1ll * suf[i + 1] * q[i].ss % mod;
  int sum = 0;
  for (int i = 1; i <= sz; i++)
    sum = (sum + 1ll * pre[i - 1] * suf[i + 1] % mod * q[i].ff) % mod;
  return mp(sum, (pw2[r - l + 1] - sum + mod) % mod);
}
int main() {
  pw2[0] = 1;
  for (int i = 1; i < 200111; i++)
    pw2[i] = pw2[i - 1] * 2 % mod;

  get1(n);
  for (int i = 1; i <= n; i++) {
    get1(f[i][0]);
    g[f[i][0]].pb(i);
    dep[i] = dep[f[i][0]] + 1;
  }
  for (int i = 1; i < 20; i++)
    for (int j = 1; j <= n; j++)
      f[j][i] = f[f[j][i - 1]][i - 1];
  dfs(0);
  int m = *max_element(dep + 1, dep + n + 1), ans = 0;
  for (int i = 0; i <= m; i++) {
    int sz = (int)vs[i].size();
    for (int j = 1; j < sz; j++)
      a[j] = dep[getlca(vs[i][j - 1], vs[i][j])];
    thor.construct(sz - 1, a);
    ans = (ans + 1ll * solve(0, sz - 1).ff * pw2[n - sz + 1]) % mod;
  }
  printendl(ans);
  return 0;
}

Fixed submission:
// This amazing code is by Eric Sunli Chen.
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>
using namespace std;
template <typename T> bool get_int(T &x) {
  char t = getchar();
  bool neg = false;
  x = 0;
  for (; (t > '9' || t < '0') && t != '-' && t != EOF; t = getchar())
    ;
  if (t == '-')
    neg = true, t = getchar();
  if (t == EOF)
    return false;
  for (; t <= '9' && t >= '0'; t = getchar())
    x = x * 10 + t - '0';
  if (neg)
    x = -x;
  return true;
}
template <typename T> void print_int(T x) {
  if (x < 0)
    putchar('-'), x = -x;
  short a[20] = {}, sz = 0;
  while (x > 0)
    a[sz++] = x % 10, x /= 10;
  if (sz == 0)
    putchar('0');
  for (int i = sz - 1; i >= 0; i--)
    putchar('0' + a[i]);
}
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define get1(a) get_int(a)
#define get2(a, b) (get1(a) && get1(b))
#define get3(a, b, c) (get1(a) && get2(b, c))
#define printendl(a) print_int(a), puts("")
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> pii;
const int inf = 0x3f3f3f3f;
const LL Linf = 1ll << 61;
const double pi = acos(-1.0);

const int mod = 1e9 + 7;
struct sparse_table {
  int lg[200111], n;
  pii v[20][200111];
  void construct(int n, int *a) {
    this->n = n;
    for (int i = 2; i <= n; i++)
      lg[i] = lg[i >> 1] + 1;
    for (int i = 1; i <= n; i++)
      v[0][i] = mp(a[i], i);
    for (int i = 1; i < 20; i++)
      for (int j = 1; j <= n; j++) {
        int nxt = j + (1 << i - 1);
        if (nxt > n)
          v[i][j] = v[i - 1][j];
        else
          v[i][j] = min(v[i - 1][j], v[i - 1][nxt]);
      }
  }
  pii query(int l, int r) {
    if (l > r)
      return mp(-1, -1);
    int len = lg[r - l + 1];
    return min(v[len][l], v[len][r - (1 << len) + 1]);
  }
} thor;
vector<int> g[200111], vs[200111];
int n, f[200111][20], dep[200111], pw2[200111], pre[200111], suf[200111],
    a[200111];

void dfs(int x) {
  for (auto v : g[x])
    dfs(v);
  vs[dep[x]].pb(x);
}
int getlca(int u, int v) {
  if (dep[u] < dep[v])
    swap(u, v);
  for (int i = 19; i >= 0; i--)
    if (dep[u] - dep[v] >> i)
      u = f[u][i];
  if (u == v)
    return u;
  for (int i = 19; i >= 0; i--)
    if (f[u][i] != f[v][i]) {
      u = f[u][i];
      v = f[v][i];
    }
  return f[u][0];
}

pii solve(int l, int r) {
  if (l == r)
    return mp(1, 1);
  int mxv = thor.query(l + 1, r).ff, curl = l;
  vector<pii> q;
  q.pb(mp(0, 0));
  while (true) {
    pii now = thor.query(curl + 1, r);
    if (now.ff != mxv) {
      q.pb(solve(curl, r));
      break;
    }
    q.pb(solve(curl, now.ss - 1));
    curl = now.ss;
  }
  int sz = (int)q.size() - 1;
  pre[0] = suf[sz + 1] = 1;
  for (int i = 1; i <= sz; i++)
    pre[i] = 1ll * pre[i - 1] * q[i].ss % mod;
  for (int i = sz; i >= 1; i--)
    suf[i] = 1ll * suf[i + 1] * q[i].ss % mod;
  int sum = 0;
  for (int i = 1; i <= sz; i++)
    sum = (sum + 1ll * pre[i - 1] * suf[i + 1] % mod * q[i].ff) % mod;
  return mp(sum, (pw2[r - l + 1] - sum + mod) % mod);
}
int main() {
  pw2[0] = 1;
  for (int i = 1; i < 200111; i++)
    pw2[i] = pw2[i - 1] * 2 % mod;

  get1(n);
  for (int i = 1; i <= n; i++) {
    get1(f[i][0]);
    g[f[i][0]].pb(i);
    dep[i] = dep[f[i][0]] + 1;
  }
  for (int i = 1; i < 20; i++)
    for (int j = 1; j <= n; j++)
      f[j][i] = f[f[j][i - 1]][i - 1];
  dfs(0);
  int m = *max_element(dep + 1, dep + n + 1), ans = 0;
  for (int i = 0; i <= m; i++) {
    int sz = (int)vs[i].size();
    for (int j = 1; j < sz; j++)
      a[j] = dep[getlca(vs[i][j - 1], vs[i][j])];
    thor.construct(sz - 1, a);
    ans = (ans + 1ll * solve(0, sz - 1).ff * pw2[n - sz + 1]) % mod;
  }
  printendl(ans);
  return 0;
}