Problem p03941 (C++)

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

using namespace std;

#define fo(i, a, b) for (int i = a; i <= b; i++)
#define fd(i, a, b) for (int i = a; i >= b; i--)
#define fi first
#define se second
#define mkp make_pair

typedef long long ll;
typedef pair<ll, ll> P;

const int N = 110000;

int n, son[N][3], v[N][3];
ll l, r, lim;
vector<P> p[N];

int read() {
  int ret = 0, sig = 1;
  char c;
  while (c = getchar(), (c < '0' || c > '9') && c != '-')
    ;
  if (c == '-')
    sig = -1;
  else
    ret = c - '0';
  while (c = getchar(), c >= '0' && c <= '9')
    ret = ret * 10 + c - '0';
  return ret * sig;
}

void dfs(int pos) {
  if (!son[pos][0]) {
    p[pos].push_back(mkp(0, 0));
    return;
  }
  int x = son[pos][1], y = son[pos][2];
  dfs(x);
  dfs(y);
  vector<P> A, B;
  for (int i = 0, j = 0; i < p[x].size(); i++) {
    while (j < p[y].size() &&
           lim - p[x][i].se - p[y][j].fi - v[pos][1] - v[pos][2] >= 0)
      j++;
    if (j)
      A.push_back(mkp(p[x][i].fi + v[pos][1], p[y][j - 1].se + v[pos][2]));
  }
  for (int i = 0, j = 0; i < p[y].size(); i++) {
    while (j < p[x].size() &&
           lim - p[y][i].se - p[x][j].fi - v[pos][1] - v[pos][2] >= 0)
      j++;
    if (j)
      B.push_back(mkp(p[y][i].fi + v[pos][2], p[x][j - 1].se + v[pos][1]));
  }
  int a = 0, b = 0;
  while (a < A.size() || b < B.size()) {
    if (b == B.size() ||
        (a != A.size() &&
         (A[a].fi < B[b].fi || (A[a].fi == B[b].fi && A[a].se < B[b].se)))) {
      if (p[pos].empty() || A[a].se < p[pos][p[pos].size() - 1].se)
        p[pos].push_back(A[a]);
      a++;
    } else {
      if (p[pos].empty() || B[b].se < p[pos][p[pos].size() - 1].se)
        p[pos].push_back(B[b]);
      b++;
    }
  }
}

bool check() {
  fo(i, 1, n) while (!p[i].empty()) p[i].pop_back();
  dfs(1);
  if (!p[1].empty())
    return true;
  return false;
}

int main() {
  n = read();
  fo(i, 2, n) {
    int fa = read(), a = read();
    son[fa][++son[fa][0]] = i;
    v[fa][son[fa][0]] = a;
    r += a;
  }
  while (l < r) {
    ll mid = (l + r) / 2;
    lim = mid;
    if (check())
      r = mid;
    else
      l = mid + 1;
  }
  printf("%lld\n", r);
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

#define fo(i, a, b) for (int i = a; i <= b; i++)
#define fd(i, a, b) for (int i = a; i >= b; i--)
#define fi first
#define se second
#define mkp make_pair

typedef long long ll;
typedef pair<ll, ll> P;

const int N = 1100000;

int n, son[N][3], v[N][3];
ll l, r, lim;
vector<P> p[N];

int read() {
  int ret = 0, sig = 1;
  char c;
  while (c = getchar(), (c < '0' || c > '9') && c != '-')
    ;
  if (c == '-')
    sig = -1;
  else
    ret = c - '0';
  while (c = getchar(), c >= '0' && c <= '9')
    ret = ret * 10 + c - '0';
  return ret * sig;
}

void dfs(int pos) {
  if (!son[pos][0]) {
    p[pos].push_back(mkp(0, 0));
    return;
  }
  int x = son[pos][1], y = son[pos][2];
  dfs(x);
  dfs(y);
  vector<P> A, B;
  for (int i = 0, j = 0; i < p[x].size(); i++) {
    while (j < p[y].size() &&
           lim - p[x][i].se - p[y][j].fi - v[pos][1] - v[pos][2] >= 0)
      j++;
    if (j)
      A.push_back(mkp(p[x][i].fi + v[pos][1], p[y][j - 1].se + v[pos][2]));
  }
  for (int i = 0, j = 0; i < p[y].size(); i++) {
    while (j < p[x].size() &&
           lim - p[y][i].se - p[x][j].fi - v[pos][1] - v[pos][2] >= 0)
      j++;
    if (j)
      B.push_back(mkp(p[y][i].fi + v[pos][2], p[x][j - 1].se + v[pos][1]));
  }
  int a = 0, b = 0;
  while (a < A.size() || b < B.size()) {
    if (b == B.size() ||
        (a != A.size() &&
         (A[a].fi < B[b].fi || (A[a].fi == B[b].fi && A[a].se < B[b].se)))) {
      if (p[pos].empty() || A[a].se < p[pos][p[pos].size() - 1].se)
        p[pos].push_back(A[a]);
      a++;
    } else {
      if (p[pos].empty() || B[b].se < p[pos][p[pos].size() - 1].se)
        p[pos].push_back(B[b]);
      b++;
    }
  }
}

bool check() {
  fo(i, 1, n) while (!p[i].empty()) p[i].pop_back();
  dfs(1);
  if (!p[1].empty())
    return true;
  return false;
}

int main() {
  n = read();
  fo(i, 2, n) {
    int fa = read(), a = read();
    son[fa][++son[fa][0]] = i;
    v[fa][son[fa][0]] = a;
    r += a;
  }
  while (l < r) {
    ll mid = (l + r) / 2;
    lim = mid;
    if (check())
      r = mid;
    else
      l = mid + 1;
  }
  printf("%lld\n", r);
  return 0;
}