Problem p03376 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define maxn 55
#define maxm 125005
#define int long long
#define INF 1e9 + 10
int n, X, D, ans, cnt, dp[maxm];
int w[maxn], val[maxn], pos[maxn];
int tot, V[maxn], W[maxn];

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

struct edge {
  int cnp, to[maxn], last[maxn], head[maxn];
  edge() { cnp = 1; }
  void add(int u, int v) { to[cnp] = v, last[cnp] = head[u], head[u] = cnp++; }
} E1;

void dfs(int u) {
  val[u] = 1;
  for (int i = E1.head[u]; i; i = E1.last[i]) {
    int v = E1.to[i];
    dfs(v);
    w[u] += w[v];
    val[u] += val[v];
  }
  cnt += val[u] * n;
  pos[u] = u;
}

bool cmp(int x, int y) { return val[x] * w[y] > val[y] * w[x]; }
void Get_min(int &x, int y) { x = x < y ? x : y; }

signed main() {
  n = read(), X = read(), D = read();
  w[1] = read();
  for (int i = 2; i <= n; i++) {
    w[i] = read();
    int x = read();
    E1.add(x, i);
  }
  dfs(1);
  sort(pos + 1, pos + n + 1, cmp);
  int tmp = min(n, D);
  for (int i = 1; i <= cnt; i++)
    dp[i] = INF;
  for (int i = 1; i <= n; i++) {
    int len = 1, lim = tmp;
    while (lim >= len) {
      V[++tot] = len * val[pos[i]];
      W[tot] = len * w[pos[i]];
      lim -= len, len <<= 1;
    }
    if (lim)
      V[++tot] = lim * val[pos[i]], W[tot] = lim * w[pos[i]];
  }
  for (int i = 1; i <= tot; i++)
    for (int j = cnt; ~j; j--)
      if (j >= V[i])
        Get_min(dp[j], dp[j - V[i]] + W[i]); // k件物品
  int ans = 0;
  for (int i = 0; i <= cnt; i++) {
    if (dp[i] > X)
      continue;
    int ret = i, left = X - dp[i];
    for (int j = 1; j <= n; j++) {
      int tem = pos[j], used = min(max(D - n, 0LL), left / w[tem]);
      if (tem == 1)
        used = left / w[tem];
      left -= w[tem] * used;
      ret += val[tem] * used;
    }
    ans = max(ans, ret);
  }
  printf("%lld\n", ans);
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define maxn 55
#define maxm 125005
#define int long long
#define INF 1e9 + 10
int n, X, D, ans, cnt, dp[maxm];
int w[maxn], val[maxn], pos[maxn];
int tot, V[maxn * maxn], W[maxn * maxn];

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

struct edge {
  int cnp, to[maxn], last[maxn], head[maxn];
  edge() { cnp = 1; }
  void add(int u, int v) { to[cnp] = v, last[cnp] = head[u], head[u] = cnp++; }
} E1;

void dfs(int u) {
  val[u] = 1;
  for (int i = E1.head[u]; i; i = E1.last[i]) {
    int v = E1.to[i];
    dfs(v);
    w[u] += w[v];
    val[u] += val[v];
  }
  cnt += val[u] * n;
  pos[u] = u;
}

bool cmp(int x, int y) { return val[x] * w[y] > val[y] * w[x]; }
void Get_min(int &x, int y) { x = x < y ? x : y; }

signed main() {
  n = read(), X = read(), D = read();
  w[1] = read();
  for (int i = 2; i <= n; i++) {
    w[i] = read();
    int x = read();
    E1.add(x, i);
  }
  dfs(1);
  sort(pos + 1, pos + n + 1, cmp);
  int tmp = min(n, D);
  for (int i = 1; i <= cnt; i++)
    dp[i] = INF;
  for (int i = 1; i <= n; i++) {
    int len = 1, lim = tmp;
    while (lim >= len) {
      V[++tot] = len * val[pos[i]];
      W[tot] = len * w[pos[i]];
      lim -= len, len <<= 1;
    }
    if (lim)
      V[++tot] = lim * val[pos[i]], W[tot] = lim * w[pos[i]];
  }
  for (int i = 1; i <= tot; i++)
    for (int j = cnt; ~j; j--)
      if (j >= V[i])
        Get_min(dp[j], dp[j - V[i]] + W[i]); // k件物品
  int ans = 0;
  for (int i = 0; i <= cnt; i++) {
    if (dp[i] > X)
      continue;
    int ret = i, left = X - dp[i];
    for (int j = 1; j <= n; j++) {
      int tem = pos[j], used = min(max(D - n, 0LL), left / w[tem]);
      if (tem == 1)
        used = left / w[tem];
      left -= w[tem] * used;
      ret += val[tem] * used;
    }
    ans = max(ans, ret);
  }
  printf("%lld\n", ans);
  return 0;
}