Problem p03376 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long lnt;
template <class T> inline void read(T &x) {
  x = 0;
  int c = getchar(), f = 1;
  for (; !isdigit(c); c = getchar())
    if (c == 45)
      f = -1;
  for (; isdigit(c); c = getchar())
    (x *= 10) += f * (c - 48);
}
int n, m, mx;
lnt X, D;
vector<int> G[55];
int rk[55];
lnt w[55], c[55], W[2505], C[2505], f[2505];
bool cmp(const int &x, const int &y) { return c[x] * w[y] > c[y] * w[x]; }
void DFS(int u) {
  c[u] = 1;
  for (int v : G[u])
    DFS(v), w[u] += w[v], c[u] += c[v];
}
int main() {
  read(n), read(X), read(D), read(w[1]);
  for (int i = 2, fa; i <= n; i++)
    read(w[i]), read(fa), G[fa].push_back(i);
  for (int i = 1; i <= n; i++)
    rk[i] = i;
  DFS(1), sort(rk + 1, rk + n + 1, cmp);
  for (int i = 1; i <= n; i++)
    mx += (int)c[i] * n;
  for (int i = 1; i <= n; i++) {
    lnt cur = 1, lft = min(1LL * n, D);
    while (cur <= lft)
      W[m] = cur * w[i], C[m] = cur * c[i], m++, lft -= cur, cur <<= 1;
    if (lft)
      W[m] = lft * w[i], C[m] = lft * c[i], m++;
  }
  memset(f, 0x3f, sizeof f), f[0] = 0;
  for (int i = 0; i < m; i++)
    for (int j = mx; j >= C[i]; j--)
      f[j] = min(f[j], f[j - C[i]] + W[i]);
  lnt ans = 0;
  for (int i = 0; i <= mx; i++)
    if (f[i] <= X) {
      lnt cur, lft = X - f[i], tot = i;
      for (int j = 1; j <= n; j++)
        if (rk[j] > 1)
          cur = min(max(D - n, 0LL), lft / w[rk[j]]), lft -= cur * w[rk[j]],
          tot += cur * c[rk[j]];
        else
          cur = lft / w[rk[j]], lft -= cur * w[rk[j]], tot += cur * c[rk[j]];
      ans = max(ans, tot);
    }
  return printf("%lld\n", ans), 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long lnt;
template <class T> inline void read(T &x) {
  x = 0;
  int c = getchar(), f = 1;
  for (; !isdigit(c); c = getchar())
    if (c == 45)
      f = -1;
  for (; isdigit(c); c = getchar())
    (x *= 10) += f * (c - 48);
}
int n, m, mx;
lnt X, D;
vector<int> G[55];
int rk[55];
lnt w[55], c[55], W[2505], C[2505], f[125005];
bool cmp(const int &x, const int &y) { return c[x] * w[y] > c[y] * w[x]; }
void DFS(int u) {
  c[u] = 1;
  for (int v : G[u])
    DFS(v), w[u] += w[v], c[u] += c[v];
}
int main() {
  read(n), read(X), read(D), read(w[1]);
  for (int i = 2, fa; i <= n; i++)
    read(w[i]), read(fa), G[fa].push_back(i);
  for (int i = 1; i <= n; i++)
    rk[i] = i;
  DFS(1), sort(rk + 1, rk + n + 1, cmp);
  for (int i = 1; i <= n; i++)
    mx += (int)c[i] * n;
  for (int i = 1; i <= n; i++) {
    lnt cur = 1, lft = min(1LL * n, D);
    while (cur <= lft)
      W[m] = cur * w[i], C[m] = cur * c[i], m++, lft -= cur, cur <<= 1;
    if (lft)
      W[m] = lft * w[i], C[m] = lft * c[i], m++;
  }
  memset(f, 0x3f, sizeof f), f[0] = 0;
  for (int i = 0; i < m; i++)
    for (int j = mx; j >= C[i]; j--)
      f[j] = min(f[j], f[j - C[i]] + W[i]);
  lnt ans = 0;
  for (int i = 0; i <= mx; i++)
    if (f[i] <= X) {
      lnt cur, lft = X - f[i], tot = i;
      for (int j = 1; j <= n; j++)
        if (rk[j] > 1)
          cur = min(max(D - n, 0LL), lft / w[rk[j]]), lft -= cur * w[rk[j]],
          tot += cur * c[rk[j]];
        else
          cur = lft / w[rk[j]], lft -= cur * w[rk[j]], tot += cur * c[rk[j]];
      ans = max(ans, tot);
    }
  return printf("%lld\n", ans), 0;
}