Problem p02876 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define XX first
#define YY second
#define pb emplace_back
#define FOR(i, a, b) for (int(i) = (a); i < (b); ++(i))
#define EFOR(i, a, b) for (int(i) = (a); i <= (b); ++(i))
#define rep(X, Y) for (int(X) = 0; (X) < (Y); ++(X))
#define REP rep
#define rrep(X, Y) for (int(X) = (Y)-1; (X) >= 0; --(X))
#define all(X) (X).begin(), (X).end()
#define eb emplace_back

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef ll LL;
typedef pii PII;
typedef pll PLL;
const ll MOD = 1e9 + 7;

#define rall(X) (X).rbegin(), (X).rend()
#define UNIQUE(X) (X).erase(unique(all(X)), (X).end())
#define reps(X, S, Y) for (int(X) = S; (X) < (Y); ++(X))
#define rreps(X, S, Y) for (int(X) = (Y)-1; (X) >= (S); --(X))
template <class T> inline bool MX(T &l, const T &r) {
  return l < r ? l = r, 1 : 0;
}
template <class T> inline bool MN(T &l, const T &r) {
  return l > r ? l = r, 1 : 0;
}

int N;
LL A[114514];
LL B[114514];

bool check(int l) {
  LL cur = 0;
  multiset<pll> as, bs;
  rep(i, N) {
    LL d = B[i] - A[i];
    if (d >= 0) {
      bs.insert(pll(B[i], A[i]));
    } else {
      as.insert(pll(A[i], B[i]));
    }
  }

  while (as.size() > l) {
    as.erase(as.find(*as.rbegin()));
  }
  while (as.size() < l && bs.size()) {
    as.insert(pll(bs.begin()->YY, bs.begin()->XX));
    bs.erase(bs.begin());
  }
  if (as.size() < l)
    return false;
  for (auto &p : as)
    cur -= p.XX;
  for (auto &p : bs)
    cur += p.XX - p.YY;

  while (!as.empty() && !bs.empty()) {
    if (bs.begin()->XX < as.rbegin()->XX) {
      cur += as.rbegin()->XX - bs.begin()->XX;
      as.erase(as.find(*as.rbegin()));
      as.insert(pll(bs.begin()->YY, bs.begin()->XX));
      bs.erase(bs.begin());
    } else
      break;
  }
  return cur >= 0;
}

pll GetAns(int l) {
  assert(l < N);
  LL cur = 0;
  multiset<pll> as, bs;
  rep(i, N) {
    LL d = B[i] - A[i];
    if (d >= 0) {
      bs.insert(pll(B[i], A[i]));
    } else {
      as.insert(pll(A[i], B[i]));
    }
  }

  multiset<pll> cs;
  while (as.size() > l) {
    cs.insert(pll(as.rbegin()->XX, as.rbegin()->YY));
    as.erase(as.find(*as.rbegin()));
  }
  while (as.size() < l && bs.size()) {
    as.insert(pll(bs.begin()->YY, bs.begin()->XX));
    bs.erase(bs.begin());
  }
  assert(as.size() >= l);
  for (auto &p : as)
    cur -= p.XX;
  for (auto &p : bs)
    cur += p.XX - p.YY;

  while (!as.empty() && !bs.empty()) {
    if (bs.begin()->XX < as.rbegin()->XX) {
      cs.insert(pll(as.rbegin()->XX, as.rbegin()->YY));
      cur += as.rbegin()->XX - bs.begin()->XX;
      as.erase(as.find(*as.rbegin()));
      as.insert(pll(bs.begin()->YY, bs.begin()->XX));
      bs.erase(bs.begin());
    } else
      break;
  }

  if (cur == 0) {
    LL p = l;
    LL q = N;
    if (p == 0)
      return pll(0, 1);
    LL g = __gcd(p, q);
    return pll(p / g, q / g);
  }

  assert(!bs.empty());
  pll ret(cur, bs.begin()->XX);
  for (auto &p : cs) {
    pll tmp(cur + p.YY - p.XX, p.YY);
    assert(tmp.XX < tmp.YY);
    if (tmp.XX * ret.YY > ret.XX * tmp.YY)
      ret = tmp;
  }

  for (auto &p : as) {
    assert(!cs.empty());
    LL v = cur + p.YY - min(bs.begin()->XX, cs.begin()->XX);
    pll tmp(v, p.YY);
    if (tmp.XX * ret.YY > ret.XX * tmp.YY)
      ret = tmp;
  }
  ret.XX += l * ret.YY;
  ret.YY *= N;
  LL g = __gcd(ret.XX, ret.YY);
  return pll(ret.XX / g, ret.YY / g);
}

signed main() {
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(0);

  cin >> N;
  rep(i, N) { cin >> A[i] >> B[i]; }

  int low = 0;
  int high = N + 1;
  while (high - low > 1) {
    int mid = (high + low) / 2;
    if (check(mid))
      low = mid;
    else
      high = mid;
  }

  // cout << low << endl;
  auto ans = GetAns(low);
  cout << ans.XX << " " << ans.YY << endl;
}


Fixed submission:
#include <bits/stdc++.h>
#define XX first
#define YY second
#define pb emplace_back
#define FOR(i, a, b) for (int(i) = (a); i < (b); ++(i))
#define EFOR(i, a, b) for (int(i) = (a); i <= (b); ++(i))
#define rep(X, Y) for (int(X) = 0; (X) < (Y); ++(X))
#define REP rep
#define rrep(X, Y) for (int(X) = (Y)-1; (X) >= 0; --(X))
#define all(X) (X).begin(), (X).end()
#define eb emplace_back

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef ll LL;
typedef pii PII;
typedef pll PLL;
const ll MOD = 1e9 + 7;

#define rall(X) (X).rbegin(), (X).rend()
#define UNIQUE(X) (X).erase(unique(all(X)), (X).end())
#define reps(X, S, Y) for (int(X) = S; (X) < (Y); ++(X))
#define rreps(X, S, Y) for (int(X) = (Y)-1; (X) >= (S); --(X))
template <class T> inline bool MX(T &l, const T &r) {
  return l < r ? l = r, 1 : 0;
}
template <class T> inline bool MN(T &l, const T &r) {
  return l > r ? l = r, 1 : 0;
}

int N;
LL A[114514];
LL B[114514];

bool check(int l) {
  LL cur = 0;
  multiset<pll> as, bs;
  rep(i, N) {
    LL d = B[i] - A[i];
    if (d >= 0) {
      bs.insert(pll(B[i], A[i]));
    } else {
      as.insert(pll(A[i], B[i]));
    }
  }

  while (as.size() > l) {
    as.erase(as.find(*as.rbegin()));
  }
  while (as.size() < l && bs.size()) {
    as.insert(pll(bs.begin()->YY, bs.begin()->XX));
    bs.erase(bs.begin());
  }
  if (as.size() < l)
    return false;
  for (auto &p : as)
    cur -= p.XX;
  for (auto &p : bs)
    cur += p.XX - p.YY;

  while (!as.empty() && !bs.empty()) {
    if (bs.begin()->XX < as.rbegin()->XX) {
      cur += as.rbegin()->XX - bs.begin()->XX;
      as.erase(as.find(*as.rbegin()));
      as.insert(pll(bs.begin()->YY, bs.begin()->XX));
      bs.erase(bs.begin());
    } else
      break;
  }
  return cur >= 0;
}

pll GetAns(int l) {
  assert(l < N);
  LL cur = 0;
  multiset<pll> as, bs;
  rep(i, N) {
    LL d = B[i] - A[i];
    if (d >= 0) {
      bs.insert(pll(B[i], A[i]));
    } else {
      as.insert(pll(A[i], B[i]));
    }
  }

  multiset<pll> cs;
  while (as.size() > l) {
    cs.insert(pll(as.rbegin()->XX, as.rbegin()->YY));
    as.erase(as.find(*as.rbegin()));
  }
  while (as.size() < l && bs.size()) {
    as.insert(pll(bs.begin()->YY, bs.begin()->XX));
    bs.erase(bs.begin());
  }
  assert(as.size() >= l);
  for (auto &p : as)
    cur -= p.XX;
  for (auto &p : bs)
    cur += p.XX - p.YY;

  while (!as.empty() && !bs.empty()) {
    if (bs.begin()->XX < as.rbegin()->XX) {
      cs.insert(pll(as.rbegin()->XX, as.rbegin()->YY));
      cur += as.rbegin()->XX - bs.begin()->XX;
      as.erase(as.find(*as.rbegin()));
      as.insert(pll(bs.begin()->YY, bs.begin()->XX));
      bs.erase(bs.begin());
    } else
      break;
  }

  if (cur == 0) {
    LL p = l;
    LL q = N;
    if (p == 0)
      return pll(0, 1);
    LL g = __gcd(p, q);
    return pll(p / g, q / g);
  }

  assert(!bs.empty());
  pll ret(cur, bs.begin()->XX);
  for (auto &p : cs) {
    pll tmp(cur + p.YY - p.XX, p.YY);
    assert(tmp.XX < tmp.YY);
    if (tmp.XX * ret.YY > ret.XX * tmp.YY)
      ret = tmp;
  }

  for (auto &p : as) {
    LL t = bs.begin()->XX;
    if (cs.size())
      MN(t, cs.begin()->XX);
    LL v = cur + p.YY - t;
    pll tmp(v, p.YY);
    if (tmp.XX * ret.YY > ret.XX * tmp.YY)
      ret = tmp;
  }
  ret.XX += l * ret.YY;
  ret.YY *= N;
  LL g = __gcd(ret.XX, ret.YY);
  return pll(ret.XX / g, ret.YY / g);
}

signed main() {
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(0);

  cin >> N;
  rep(i, N) { cin >> A[i] >> B[i]; }

  int low = 0;
  int high = N + 1;
  while (high - low > 1) {
    int mid = (high + low) / 2;
    if (check(mid))
      low = mid;
    else
      high = mid;
  }

  // cout << low << endl;
  auto ans = GetAns(low);
  cout << ans.XX << " " << ans.YY << endl;
}