Problem p03499 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_poizcy.hpp>
typedef long long ll;
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define mem(a, h) memset(a, (h), sizeof(a))
#define se second
#define fi first
#define por(a, b) (((a % MOD) * (b % MOD)) % MOD)
#define forg(i, b, e, c) for (ll i = (ll)b; i < (ll)e; i += c)
#define forr(i, b, e) for (ll i = b; i < e; i++)

using namespace std;
// using namespace __gnu_pbds;
typedef double lldb;
typedef pair<ll, ll> ii;
typedef pair<ii, ll> iii;
typedef pair<double, double> iidb;
// typedef
// tree<ii,null_type,less<ii>,rb_tree_tag,tree_order_statistics_node_update>
// ordered_set;
const ll INF = 1e9 + 7;
const double PI = acos(-1);
#define initseg ll new_nodo = (pnodo * 2), mid = (iz + der) / 2;

// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define offset 3000
#define ptr nodo *
const ll MOD = 1e9 + 7;
#define tam 234
#define cmplog 18
using namespace std;
vector<ii> cam;
ll li[tam], ri[tam];
ii sp[tam][cmplog];
ll nxtpot[tam]; // LCA

vector<ll> g[tam];

vector<ll> elements[tam];
ll dp[tam], dpinv[tam], solved[tam], arrpa[tam];

void dfs0(ll u, ll pa, ll depth) {

  li[u] = cam.size();
  elements[depth].pb(u);
  cam.pb({depth, u});
  for (ll w : g[u]) {
    if (w == pa)
      continue;

    dfs0(w, u, depth + 1);
    cam.pb({depth, u});
  }
  cam.pb({depth, u});
  ri[u] = cam.size() - 1;
}
ll n;
ii query(ll iz, ll der) {
  iz = li[iz];
  der = li[der];
  if (iz > der)
    swap(iz, der);

  ll d = der - iz + 1;
  d = nxtpot[d];
  auto res = min(sp[iz][d], sp[der - (1 << d) + 1][d]);
  return res;
}
void initlca() {
  nxtpot[1] = 0;
  forr(i, 2, tam) nxtpot[i] = nxtpot[i / 2] + 1;
  dfs0(0, 0, 0);
  forr(i, 0, cam.size()) { sp[i][0] = cam[i]; }
  forr(bit, 1, cmplog) {
    forr(i, 0, cam.size()) sp[i][bit] = min(
        sp[i][bit - 1], sp[min((ll)cam.size(), i + (1 << (bit - 1)))][bit - 1]);
  }
}

ll pot(ll b, ll e) {
  ll res = 1;
  while (e) {
    if (e & 1)
      res *= b, res %= MOD;
    b *= b, b %= MOD, e /= 2;
  }
  return res;
}
// solving
vector<ll> g2[tam];

ll findpa(ll u) {
  if (arrpa[u] == u)
    return u;
  return arrpa[u] = findpa(arrpa[u]);
}

void solve(ll u) {
  dp[u] = dpinv[u] = 0;
  dpinv[u] = 1;
  ll totneg = 1, tot2 = 0;
  for (ll w : g2[u]) {
    assert(solved[w]);
    totneg *= dpinv[w];
    totneg %= MOD;
    tot2 += dp[w] * pot(dpinv[w], MOD - 2);
    tot2 %= MOD;

    dpinv[u] *= (dp[w] + dpinv[w]);
    dpinv[u] %= MOD;
  }
  dp[u] = totneg * tot2;
  dp[u] %= MOD;
  dpinv[u] = dpinv[u] - dp[u];
  dpinv[u] %= MOD;
  dpinv[u] += MOD;
  dpinv[u] %= MOD;

  solved[u] = 1;
}
void join(ll vlca, ll iz, ll der) {
  iz = findpa(iz);
  der = findpa(der);
  if (iz != vlca && !solved[iz])
    solve(iz);
  if (der != vlca && !solved[der])
    solve(der);

  ll pa1 = findpa(iz), pa2 = findpa(der);
  arrpa[pa1] = arrpa[pa2] = vlca;
  assert(findpa(vlca) == vlca);
  if (iz != vlca)
    g2[vlca].pb(iz);
  if (der != vlca)
    g2[vlca].pb(der);
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  cin >> n;
  ll iz;
  forr(i, 1, n + 1) {
    cin >> iz;
    g[i].pb(iz);
    g[iz].pb(i);
  }
  initlca();
  ll total = 0;
  forr(l, 0, tam) {
    if (elements[l].empty())
      break;
    if (elements[l].size() == 1) {
      total += pot(2, n);
      total %= MOD;
      continue;
    }
    auto v = elements[l];

    for (ll x : v) {

      solved[x] = 1;
      dp[x] = 1;
      dpinv[x] = 1;
      arrpa[x] = x;
      g2[x].clear();
    }

    vector<iii> joins;
    ii minn = {1e9, 1e9};
    forr(i, 0, v.size() - 1) {
      joins.pb({query(v[i], v[i + 1]), i});
      ll extra = joins.back().fi.se;
      minn = min(minn, joins.back().fi);

      solved[extra] = 0;
      arrpa[extra] = extra;
      g2[extra].clear();
    }

    sort(all(joins));
    reverse(all(joins));
    for (auto par : joins) {
      ll vlca = par.fi.se, pos = par.se;

      join(vlca, v[pos], v[pos + 1]);
    }
    int ultimo = minn.se;
    solve(ultimo);

    total += dp[ultimo] * pot(2, n + 1 - elements[l].size());
    total %= MOD;
  }

  cout << total << endl;
}

Fixed submission:
#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_poizcy.hpp>
typedef long long ll;
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define mem(a, h) memset(a, (h), sizeof(a))
#define se second
#define fi first
#define por(a, b) (((a % MOD) * (b % MOD)) % MOD)
#define forg(i, b, e, c) for (ll i = (ll)b; i < (ll)e; i += c)
#define forr(i, b, e) for (ll i = b; i < e; i++)

using namespace std;
// using namespace __gnu_pbds;
typedef double lldb;
typedef pair<ll, ll> ii;
typedef pair<ii, ll> iii;
typedef pair<double, double> iidb;
// typedef
// tree<ii,null_type,less<ii>,rb_tree_tag,tree_order_statistics_node_update>
// ordered_set;
const ll INF = 1e9 + 7;
const double PI = acos(-1);
#define initseg ll new_nodo = (pnodo * 2), mid = (iz + der) / 2;

// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define offset 3000
#define ptr nodo *
const ll MOD = 1e9 + 7;
#define tam 600234
#define cmplog 20
using namespace std;
vector<ii> cam;
ll li[tam], ri[tam];
ii sp[tam][cmplog];
ll nxtpot[tam]; // LCA

vector<ll> g[tam];

vector<ll> elements[tam];
ll dp[tam], dpinv[tam], solved[tam], arrpa[tam];

void dfs0(ll u, ll pa, ll depth) {

  li[u] = cam.size();
  elements[depth].pb(u);
  cam.pb({depth, u});
  for (ll w : g[u]) {
    if (w == pa)
      continue;

    dfs0(w, u, depth + 1);
    cam.pb({depth, u});
  }
  cam.pb({depth, u});
  ri[u] = cam.size() - 1;
}
ll n;
ii query(ll iz, ll der) {
  iz = li[iz];
  der = li[der];
  if (iz > der)
    swap(iz, der);

  ll d = der - iz + 1;
  d = nxtpot[d];
  auto res = min(sp[iz][d], sp[der - (1 << d) + 1][d]);
  return res;
}
void initlca() {
  nxtpot[1] = 0;
  forr(i, 2, tam) nxtpot[i] = nxtpot[i / 2] + 1;
  dfs0(0, 0, 0);
  forr(i, 0, cam.size()) { sp[i][0] = cam[i]; }
  forr(bit, 1, cmplog) {
    forr(i, 0, cam.size()) sp[i][bit] = min(
        sp[i][bit - 1], sp[min((ll)cam.size(), i + (1 << (bit - 1)))][bit - 1]);
  }
}

ll pot(ll b, ll e) {
  ll res = 1;
  while (e) {
    if (e & 1)
      res *= b, res %= MOD;
    b *= b, b %= MOD, e /= 2;
  }
  return res;
}
// solving
vector<ll> g2[tam];

ll findpa(ll u) {
  if (arrpa[u] == u)
    return u;
  return arrpa[u] = findpa(arrpa[u]);
}

void solve(ll u) {
  dp[u] = dpinv[u] = 0;
  dpinv[u] = 1;
  ll totneg = 1, tot2 = 0;
  for (ll w : g2[u]) {
    assert(solved[w]);
    totneg *= dpinv[w];
    totneg %= MOD;
    tot2 += dp[w] * pot(dpinv[w], MOD - 2);
    tot2 %= MOD;

    dpinv[u] *= (dp[w] + dpinv[w]);
    dpinv[u] %= MOD;
  }
  dp[u] = totneg * tot2;
  dp[u] %= MOD;
  dpinv[u] = dpinv[u] - dp[u];
  dpinv[u] %= MOD;
  dpinv[u] += MOD;
  dpinv[u] %= MOD;

  solved[u] = 1;
}
void join(ll vlca, ll iz, ll der) {
  iz = findpa(iz);
  der = findpa(der);
  if (iz != vlca && !solved[iz])
    solve(iz);
  if (der != vlca && !solved[der])
    solve(der);

  ll pa1 = findpa(iz), pa2 = findpa(der);
  arrpa[pa1] = arrpa[pa2] = vlca;
  assert(findpa(vlca) == vlca);
  if (iz != vlca)
    g2[vlca].pb(iz);
  if (der != vlca)
    g2[vlca].pb(der);
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  cin >> n;
  ll iz;
  forr(i, 1, n + 1) {
    cin >> iz;
    g[i].pb(iz);
    g[iz].pb(i);
  }
  initlca();
  ll total = 0;
  forr(l, 0, tam) {
    if (elements[l].empty())
      break;
    if (elements[l].size() == 1) {
      total += pot(2, n);
      total %= MOD;
      continue;
    }
    auto v = elements[l];

    for (ll x : v) {

      solved[x] = 1;
      dp[x] = 1;
      dpinv[x] = 1;
      arrpa[x] = x;
      g2[x].clear();
    }

    vector<iii> joins;
    ii minn = {1e9, 1e9};
    forr(i, 0, v.size() - 1) {
      joins.pb({query(v[i], v[i + 1]), i});
      ll extra = joins.back().fi.se;
      minn = min(minn, joins.back().fi);

      solved[extra] = 0;
      arrpa[extra] = extra;
      g2[extra].clear();
    }

    sort(all(joins));
    reverse(all(joins));
    for (auto par : joins) {
      ll vlca = par.fi.se, pos = par.se;

      join(vlca, v[pos], v[pos + 1]);
    }
    int ultimo = minn.se;
    solve(ultimo);

    total += dp[ultimo] * pot(2, n + 1 - elements[l].size());
    total %= MOD;
  }

  cout << total << endl;
}