Problem p03376 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
using lint = long long int;
using Plint = pair<lint, lint>;

lint N, X, D;

vector<int> par;
vector<vector<int>> chi;
vector<lint> m, ms, ns;

void dfsms(int i) {
  ms[i] = m[i];
  ns[i] = 1;
  for (auto v : chi[i]) {
    dfsms(v);
    ms[i] += ms[v];
    ns[i] += ns[v];
  }
}

bool efficient(const Plint &a, const Plint &b) {
  return a.first * b.second > b.first * a.second;
}

int main() {
  cin >> N >> X >> D;
  m.resize(N);
  par.resize(N);
  chi.resize(N);
  cin >> m[0];
  par[0] = -1;
  for (int i = 1; i < N; i++) {
    cin >> m[i] >> par[i];
    par[i]--;
    chi[par[i]].push_back(i);
  }

  ms.resize(N);
  ns.resize(N);
  dfsms(0);

  vector<Plint> info;
  for (int i = 0; i < N; i++)
    info.push_back(Plint(ns[i], ms[i]));
  sort(info.begin(), info.end(), efficient);
  // for (auto v : info) cout << v.first << " " << v.second << endl;

  vector<vector<lint>> dp(N + 1, vector<lint>(2501, -1));
  dp[0][0] = 0;
  vector<lint> maxnum(N + 1);

  for (int i = 1; i <= N; i++) {
    lint v = info[i - 1].first;
    lint w = info[i - 1].second;

    maxnum[i] = maxnum[i - 1];
    for (int j = 0; j < 2501; j++)
      if (dp[i - 1][j] >= 0) {
        if (v != N)
          maxnum[i] = max(maxnum[i], maxnum[i - 1] - j +
                                         min((X - dp[i - 1][j]) / w, D) * v);
        else
          maxnum[i] =
              max(maxnum[i], maxnum[i - 1] - j + (X - dp[i - 1][j]) / w * v);
      }

    for (int j = 0; j < 2501; j++)
      if (dp[i - 1][j] >= 0) {
        for (int k = (maxnum[i] - maxnum[i - 1] + j) % v; k < 2501; k += v) {
          lint need = (maxnum[i] - k) - (maxnum[i - 1] - j);
          if (need < 0)
            continue;
          if (v != N && need > D * v)
            continue;
          lint dp_tmp = dp[i - 1][j] + need / v * w;
          if (dp_tmp > X)
            continue;
          if (dp[i][k] < 0 || dp[i][k] > dp_tmp)
            dp[i][k] = dp_tmp;
        }
      }
  }
  // for (auto vec : dp)
  // {
  //     for (auto v : vec) cout << v << " ";
  //     cout << endl;
  // }
  // for (auto v : maxnum) cout << v << " ";
  cout << maxnum[N] << endl;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using lint = long long int;
using Plint = pair<lint, lint>;

lint N, X, D;

vector<int> par;
vector<vector<int>> chi;
vector<lint> m, ms, ns;

void dfsms(int i) {
  ms[i] = m[i];
  ns[i] = 1;
  for (auto v : chi[i]) {
    dfsms(v);
    ms[i] += ms[v];
    ns[i] += ns[v];
  }
}

bool efficient(const Plint &a, const Plint &b) {
  return a.first * b.second > b.first * a.second;
}

int main() {
  cin >> N >> X >> D;
  m.resize(N);
  par.resize(N);
  chi.resize(N);
  cin >> m[0];
  par[0] = -1;
  for (int i = 1; i < N; i++) {
    cin >> m[i] >> par[i];
    par[i]--;
    chi[par[i]].push_back(i);
  }

  ms.resize(N);
  ns.resize(N);
  dfsms(0);

  vector<Plint> info;
  for (int i = 0; i < N; i++)
    info.push_back(Plint(ns[i], ms[i]));
  sort(info.begin(), info.end(), efficient);
  // for (auto v : info) cout << v.first << " " << v.second << endl;

  // vector<vector<lint>> dp(N+1, vector<lint>(2501, -1));
  array<array<lint, 2501>, 51> dp;
  for (auto &vec : dp)
    for (auto &v : vec)
      v = -1;

  dp[0][0] = 0;
  vector<lint> maxnum(N + 1);

  for (int i = 1; i <= N; i++) {
    lint v = info[i - 1].first;
    lint w = info[i - 1].second;

    maxnum[i] = maxnum[i - 1];
    for (int j = 0; j < 2501; j++)
      if (dp[i - 1][j] >= 0) {
        if (v != N)
          maxnum[i] = max(maxnum[i], maxnum[i - 1] - j +
                                         min((X - dp[i - 1][j]) / w, D) * v);
        else
          maxnum[i] =
              max(maxnum[i], maxnum[i - 1] - j + (X - dp[i - 1][j]) / w * v);
      }

    for (int j = 0; j < 2501; j++)
      if (dp[i - 1][j] >= 0) {
        for (int k = (maxnum[i] - maxnum[i - 1] + j) % v; k < 2501; k += v) {
          lint need = (maxnum[i] - k) - (maxnum[i - 1] - j);
          if (need < 0)
            continue;
          if (v != N && need > D * v)
            continue;
          lint dp_tmp = dp[i - 1][j] + need / v * w;
          if (dp_tmp > X)
            continue;
          if (dp[i][k] < 0 || dp[i][k] > dp_tmp)
            dp[i][k] = dp_tmp;
        }
      }
  }
  // for (auto vec : dp)
  // {
  //     for (auto v : vec) cout << v << " ";
  //     cout << endl;
  // }
  // for (auto v : maxnum) cout << v << " ";
  cout << maxnum[N] << endl;
}