Problem p03019 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cassert>
#include <chrono>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <vector>

using namespace std;

const int MAXN = 100000;

int x;

struct Exam {
  int b;
  int l;
  int u;

  long long total() const { return 1LL * b * l + 1LL * (x - b) * u; }

  long long partial(long long a) {
    if (a <= b)
      return 1LL * a * l;
    else
      return 1LL * b * l + 1LL * (a - b) * u;
  }

  bool operator<(const Exam &other) const { return total() >= other.total(); }
};

Exam v[1 + MAXN];
long long sum[1 + MAXN];
priority_queue<pair<int, int>> upHeap;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>>
    downHeap;

bool check(int n, long long limit, long long taken) {
  if (1LL * n * x == taken)
    return sum[n] >= limit;
  long long r = taken % x, c = taken / x;
  bool found = false;
  for (int i = 1; i <= n; i++)
    if (i <= c)
      found |= sum[c + 1] - v[i].total() + v[i].partial(r) >= limit;
    else
      found |= sum[c] + v[i].partial(r) >= limit;
  return found;
}

int main() {
  // ifstream cin("input.in");
  int n;
  cin >> n >> x;
  long long limit = 0;
  for (int i = 1; i <= n; i++) {
    cin >> v[i].b >> v[i].l >> v[i].u;
    limit += 1LL * v[i].b * v[i].l;
  }
  sort(v + 1, v + n + 1);
  for (int i = 1; i <= n; i++)
    sum[i] = sum[i - 1] + v[i].total();
  long long left = 0, right = 1LL * n * x, answer = 1LL * n * x;
  while (left <= right) {
    long long middle = (left + right) / 2;
    if (check(n, limit, middle)) {
      answer = middle;
      right = middle - 1;
    } else
      left = middle + 1;
  }
  cout << answer << "\n";
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cassert>
#include <chrono>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <vector>

using namespace std;

const int MAXN = 100000;

int x;

struct Exam {
  int b;
  int l;
  int u;

  long long total() const { return 1LL * b * l + 1LL * (x - b) * u; }

  long long partial(long long a) {
    if (a <= b)
      return 1LL * a * l;
    else
      return 1LL * b * l + 1LL * (a - b) * u;
  }

  bool operator<(const Exam &other) const { return total() > other.total(); }
};

Exam v[1 + MAXN];
long long sum[1 + MAXN];
priority_queue<pair<int, int>> upHeap;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>>
    downHeap;

bool check(int n, long long limit, long long taken) {
  if (1LL * n * x == taken)
    return sum[n] >= limit;
  long long r = taken % x, c = taken / x;
  bool found = false;
  for (int i = 1; i <= n; i++)
    if (i <= c)
      found |= sum[c + 1] - v[i].total() + v[i].partial(r) >= limit;
    else
      found |= sum[c] + v[i].partial(r) >= limit;
  return found;
}

int main() {
  // ifstream cin("input.in");
  int n;
  cin >> n >> x;
  long long limit = 0;
  for (int i = 1; i <= n; i++) {
    cin >> v[i].b >> v[i].l >> v[i].u;
    limit += 1LL * v[i].b * v[i].l;
  }
  sort(v + 1, v + n + 1);
  for (int i = 1; i <= n; i++)
    sum[i] = sum[i - 1] + v[i].total();
  long long left = 0, right = 1LL * n * x, answer = 1LL * n * x;
  while (left <= right) {
    long long middle = (left + right) / 2;
    if (check(n, limit, middle)) {
      answer = middle;
      right = middle - 1;
    } else
      left = middle + 1;
  }
  cout << answer << "\n";
  return 0;
}