Problem p03376 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

template <typename T> inline void check_min(T a, T &b) {
  if (a < b)
    b = a;
}
template <typename T> inline void check_max(T a, T &b) {
  if (a > b)
    b = a;
}

namespace xiangbudaoxiangbudao {
typedef long long ll;
const int N = 52, M = N * N * N;
const ll INF = 4223372036854775807ll;

struct NIDAGE {
  ll f[M];
  void reset() {
    f[0] = 0;
    for (int i = 1; i < M; i++)
      f[i] = INF;
  }
  void put(ll cost, int val) {
    for (int i = M - 1; i >= val; i--)
      check_min(f[i - val] + cost, f[i]);
  }
  void insert(ll cost, int val, int num) {
    for (int k = 1; k <= num; k <<= 1)
      put(cost * k, val * k), num -= k;
    if (num)
      put(cost * num, val * num);
  }
} d;

struct item {
  ll cost;
  int val, num;
} s[N];

bool operator<(item A, item B) { return A.val * B.cost > B.val * A.cost; }

int fa[N];

int n, m, cnt;

void initialize() {
  scanf("%d%d%d", &n, &m, &cnt);
  scanf("%lld", &s[1].cost);
  for (int i = 2; i <= n; i++)
    scanf("%lld%d", &s[i].cost, fa + i);
  for (int i = 1; i <= n; i++)
    s[i].val = 1;
  for (int i = n; i; i--)
    s[fa[i]].val += s[i].val, s[fa[i]].cost += s[i].cost;

  s[1].num = m / s[1].cost + 2333;
  for (int i = 2; i <= n; i++)
    s[i].num = cnt;
  std::sort(s + 1, s + n + 1);

  d.reset();
  for (int i = 1; i <= n; i++) {
    int tmp = std::min(50, s[i].num);
    s[i].num -= tmp;
    d.insert(s[i].cost, s[i].val, tmp);
  }
}
ll calc(ll lim) {
  ll ret = 0;
  for (int i = 1; i <= n; i++) {
    if (s[i].cost <= lim / s[i].num) {
      ret += s[i].num * s[i].val;
      lim -= s[i].cost * s[i].num;
    } else {
      ret += (lim / s[i].cost) * s[i].val;
      break;
    }
  }
  return ret;
}
void solve() {
  initialize();
  ll ans = 0;

  for (int i = 0; i < M; i++) {
    if (d.f[i] > m)
      break;
    check_max(i + calc(m - d.f[i]), ans);
  }
  printf("%lld\n", ans);
}
} // namespace xiangbudaoxiangbudao

int main() {
  xiangbudaoxiangbudao::solve();
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

template <typename T> inline void check_min(T a, T &b) {
  if (a < b)
    b = a;
}
template <typename T> inline void check_max(T a, T &b) {
  if (a > b)
    b = a;
}

namespace xiangbudaoxiangbudao {
typedef long long ll;
const int N = 52, M = N * N * N;
const ll INF = 4223372036854775807ll;

struct NIDAGE {
  ll f[M];
  void reset() {
    f[0] = 0;
    for (int i = 1; i < M; i++)
      f[i] = INF;
  }
  void put(ll cost, int val) {
    for (int i = M - 1; i >= val; i--)
      check_min(f[i - val] + cost, f[i]);
  }
  void insert(ll cost, int val, int num) {
    for (int k = 1; k <= num; k <<= 1)
      put(cost * k, val * k), num -= k;
    if (num)
      put(cost * num, val * num);
  }
} d;

struct item {
  ll cost;
  int val, num;
} s[N];

bool operator<(item A, item B) { return A.val * B.cost > B.val * A.cost; }

int fa[N];

int n, m, cnt;

void initialize() {
  scanf("%d%d%d", &n, &m, &cnt);
  scanf("%lld", &s[1].cost);
  for (int i = 2; i <= n; i++)
    scanf("%lld%d", &s[i].cost, fa + i);
  for (int i = 1; i <= n; i++)
    s[i].val = 1;
  for (int i = n; i; i--)
    s[fa[i]].val += s[i].val, s[fa[i]].cost += s[i].cost;

  s[1].num = m / s[1].cost + 2333;
  for (int i = 2; i <= n; i++)
    s[i].num = cnt;
  std::sort(s + 1, s + n + 1);

  d.reset();
  for (int i = 1; i <= n; i++) {
    int tmp = std::min(50, s[i].num);
    s[i].num -= tmp;
    d.insert(s[i].cost, s[i].val, tmp);
  }
}
ll calc(ll lim) {
  ll ret = 0;
  for (int i = 1; i <= n; i++) {
    if (s[i].num == 0 || s[i].cost <= lim / s[i].num) {
      ret += s[i].num * s[i].val;
      lim -= s[i].cost * s[i].num;
    } else {
      ret += (lim / s[i].cost) * s[i].val;
      break;
    }
  }
  return ret;
}
void solve() {
  initialize();
  ll ans = 0;

  for (int i = 0; i < M; i++) {
    if (d.f[i] > m)
      break;
    check_max(i + calc(m - d.f[i]), ans);
  }
  printf("%lld\n", ans);
}
} // namespace xiangbudaoxiangbudao

int main() {
  xiangbudaoxiangbudao::solve();
  return 0;
}