Problem p03376 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#define MAXN 1000005
#define PLI pair<long long, int>
#define fi first
#define se second
#define mp make_pair
#define ha 99994711
#define ba 823
// #define ivorysi
using namespace std;
typedef long long int64;
int N, Lim, dis;
int64 X, D, m[55], cost[55];
int p[55], siz[55], q[55], id[55];
int64 dp[125005], ans;
int ql, qr;
bool cmp(int a, int b) { return siz[a] * cost[b] > siz[b] * cost[a]; }
void update(int64 &x, int64 y) { x = min(x, y); }
void Solve() {
  scanf("%d%lld%lld", &N, &X, &D);
  Lim = N * N * N;
  scanf("%d", &m[1]);
  for (int i = 2; i <= N; ++i)
    scanf("%d%d", &m[i], &p[i]);
  for (int i = N; i >= 1; --i) {
    cost[i] += m[i];
    siz[i]++;
    cost[p[i]] += cost[i];
    siz[p[i]] += siz[i];
    id[i] = i;
  }
  for (int i = 1; i <= Lim; ++i)
    dp[i] = X + 1;
  sort(id + 1, id + N + 1, cmp);
  dis = min(N, (int)D);
  for (int k = 1; k <= N; ++k) {
    int s = siz[id[k]];
    int64 v = cost[id[k]];
    for (int j = 0; j < s; ++j) {
      int T = min((Lim - j) / s, dis);
      if (id[k] == 1)
        T = min((Lim - j) / s, N);
      int p = (Lim - j) / s;
      ql = 1, qr = 0;
      for (int i = (Lim - j) / s; i >= 1; --i) {
        while (p >= 0 && i - p <= T) {
          while (ql <= qr &&
                 dp[j + q[qr] * s] - q[qr] * v > dp[j + p * s] - p * v)
            --qr;
          q[++qr] = p;
          --p;
        }
        while (ql <= qr && q[ql] >= i)
          ++ql;
        if (ql <= qr) {
          update(dp[j + i * s], dp[j + q[ql] * s] + (i - q[ql]) * v);
        }
      }
    }
  }
  for (int i = 0; i <= Lim; ++i) {
    int64 T = X - dp[i];
    if (T < 0)
      continue;
    int64 tmp = i;
    int num;
    for (int k = 1; k <= N; ++k) {
      if (id[k] == 1)
        num = T;
      else
        num = D - dis;
      int t = min(T / cost[id[k]], (int64)num);
      tmp += 1LL * t * siz[id[k]];
      T -= t * cost[id[k]];
    }
    ans = max(ans, tmp);
  }
  printf("%lld\n", ans);
}
int main() {
#ifdef ivorysi
  freopen("f1.in", "r", stdin);
#endif
  Solve();
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#define MAXN 1000005
#define PLI pair<long long, int>
#define fi first
#define se second
#define mp make_pair
#define ha 99994711
#define ba 823
// #define ivorysi
using namespace std;
typedef long long int64;
int N, Lim, dis;
int64 X, D, m[55], cost[55];
int p[55], siz[55], q[125005], id[55];
int64 dp[125005], ans;
int ql, qr;
bool cmp(int a, int b) { return siz[a] * cost[b] > siz[b] * cost[a]; }
void update(int64 &x, int64 y) { x = min(x, y); }
void Solve() {
  scanf("%d%lld%lld", &N, &X, &D);
  Lim = N * N * N;
  scanf("%d", &m[1]);
  for (int i = 2; i <= N; ++i)
    scanf("%d%d", &m[i], &p[i]);
  for (int i = N; i >= 1; --i) {
    cost[i] += m[i];
    siz[i]++;
    cost[p[i]] += cost[i];
    siz[p[i]] += siz[i];
    id[i] = i;
  }
  for (int i = 1; i <= Lim; ++i)
    dp[i] = X + 1;
  sort(id + 1, id + N + 1, cmp);
  dis = min(N, (int)D);
  for (int k = 1; k <= N; ++k) {
    int s = siz[id[k]];
    int64 v = cost[id[k]];
    for (int j = 0; j < s; ++j) {
      int T = min((Lim - j) / s, dis);
      if (id[k] == 1)
        T = min((Lim - j) / s, N);
      int p = (Lim - j) / s;
      ql = 1, qr = 0;
      for (int i = (Lim - j) / s; i >= 1; --i) {
        while (p >= 0 && i - p <= T) {
          while (ql <= qr &&
                 dp[j + q[qr] * s] - q[qr] * v > dp[j + p * s] - p * v)
            --qr;
          q[++qr] = p;
          --p;
        }
        while (ql <= qr && q[ql] >= i)
          ++ql;
        if (ql <= qr) {
          update(dp[j + i * s], dp[j + q[ql] * s] + (i - q[ql]) * v);
        }
      }
    }
  }
  for (int i = 0; i <= Lim; ++i) {
    int64 T = X - dp[i];
    if (T < 0)
      continue;
    int64 tmp = i;
    int num;
    for (int k = 1; k <= N; ++k) {
      if (id[k] == 1)
        num = T;
      else
        num = D - dis;
      int t = min(T / cost[id[k]], (int64)num);
      tmp += 1LL * t * siz[id[k]];
      T -= t * cost[id[k]];
    }
    ans = max(ans, tmp);
  }
  printf("%lld\n", ans);
}
int main() {
#ifdef ivorysi
  freopen("f1.in", "r", stdin);
#endif
  Solve();
  return 0;
}