Problem p02821 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

using i32 = std::int_fast32_t;
using i64 = std::int_fast64_t;
template <typename T>
constexpr T inf =
    numeric_limits<T>::has_infinity ? numeric_limits<T>::infinity()
                                    : numeric_limits<T>::max() / 4;

#define REP(i, stop) FOR(i, 0, stop)
#define FOR(i, start, stop)                                                    \
  for (int i = start, i##_len = stop; i < i##_len; ++i)
#define RREP(i, n) for (int i = n; i-- > 0;)
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define COMP(key) [](const auto &a, const auto &b) { return a.key < b.key; }

template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &a) {
  return is >> a.first >> a.second;
}
template <typename T> istream &operator>>(istream &is, vector<T> &a) {
  for (T &x : a)
    is >> x;
  return is;
}

void LOG(const int &x) { cerr << x << "\n"; }
template <typename T> void LOG(const vector<T> &a) {
  for (const T &x : a)
    cerr << x << " ";
  cerr << "\n";
}
template <typename T, std::size_t S> void LOG(const T (&a)[S]) {
  REP(i, S) cerr << a[i] << " ";
  cerr << "\n";
}
template <typename T, std::size_t S, std::size_t R>
void LOG(const T (&a)[S][R]) {
  REP(i, S) {
    REP(j, R) cerr << a[i][j] << " ";
    cerr << "\n";
  }
}

i64 ceil(i64 a, i64 b) { return (a - 1) / b + 1; }
i64 gcd(i64 a, i64 b) {
  while (b != 0) {
    i64 t = b;
    b = a % b;
    a = t;
  }
  return a;
}
i64 lcm(i64 a, i64 b) { return a / gcd(a, b) * b; }
i64 gcd(const vector<i64> &v) {
  return accumulate(ALL(v), 1LL, static_cast<i64 (*)(i64, i64)>(gcd));
}
i64 lcm(const vector<i64> &v) {
  return v.empty() ? 0LL
                   : accumulate(v.begin() + 1, v.end(), v[0],
                                static_cast<i64 (*)(i64, i64)>(lcm));
}
i64 pow(i64 x, i64 y, i64 z) {
  i64 a = 1;
  while (y > 0) {
    if (y & 1)
      a = a * x % z;
    x = x * x % z;
    y /= 2;
  }
  return a;
}
i64 inv(i64 x, i64 m) { return pow(x, m - 2, m); }

struct InitCpp {
  InitCpp() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
  }
} initCpp;

const i64 INF = inf<i64>;
using P = pair<i64, i64>;
using T = pair<i64, P>;
const i64 M = 1000000007;
signed main() {
  i64 N, M;
  cin >> N >> M;
  vector<i64> A(N);
  cin >> A;
  sort(ALL(A));
  vector<i64> S(N + 1);
  REP(i, N) S[i + 1] = S[i] + A[i];
  i64 h_ng = 0;
  i64 h_ok = A[N - 1] * 2;
  i64 h = h_ok;
  i64 s = 0;
  i64 q = 0;
  i64 r = 0;
  i64 ans = 0;
  while (h_ok > h_ng + 1) {
    h = (h_ok + h_ng) / 2;
    s = 0;
    q = 0;
    r = 0;
    REP(i, N) {
      i64 ge = lower_bound(ALL(A), h - A[i]) - A.begin();
      i64 gt = upper_bound(ALL(A), h - A[i]) - A.begin();
      q += N - gt;
      r += gt - ge;
      s += S[N] - S[gt] + A[i] * (N - gt);
    }
    if (q <= M) {
      h_ok = h;
      if (M <= q + r) {
        cout << (s + (M - q) * h) << endl;
        exit(0);
      }
    } else {
      h_ng = h;
    }
  }
  exit(1);
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

using i32 = std::int_fast32_t;
using i64 = std::int_fast64_t;
template <typename T>
constexpr T inf =
    numeric_limits<T>::has_infinity ? numeric_limits<T>::infinity()
                                    : numeric_limits<T>::max() / 4;

#define REP(i, stop) FOR(i, 0, stop)
#define FOR(i, start, stop)                                                    \
  for (int i = start, i##_len = stop; i < i##_len; ++i)
#define RREP(i, n) for (int i = n; i-- > 0;)
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define COMP(key) [](const auto &a, const auto &b) { return a.key < b.key; }

template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &a) {
  return is >> a.first >> a.second;
}
template <typename T> istream &operator>>(istream &is, vector<T> &a) {
  for (T &x : a)
    is >> x;
  return is;
}

void LOG(const int &x) { cerr << x << "\n"; }
template <typename T> void LOG(const vector<T> &a) {
  for (const T &x : a)
    cerr << x << " ";
  cerr << "\n";
}
template <typename T, std::size_t S> void LOG(const T (&a)[S]) {
  REP(i, S) cerr << a[i] << " ";
  cerr << "\n";
}
template <typename T, std::size_t S, std::size_t R>
void LOG(const T (&a)[S][R]) {
  REP(i, S) {
    REP(j, R) cerr << a[i][j] << " ";
    cerr << "\n";
  }
}

i64 ceil(i64 a, i64 b) { return (a - 1) / b + 1; }
i64 gcd(i64 a, i64 b) {
  while (b != 0) {
    i64 t = b;
    b = a % b;
    a = t;
  }
  return a;
}
i64 lcm(i64 a, i64 b) { return a / gcd(a, b) * b; }
i64 gcd(const vector<i64> &v) {
  return accumulate(ALL(v), 1LL, static_cast<i64 (*)(i64, i64)>(gcd));
}
i64 lcm(const vector<i64> &v) {
  return v.empty() ? 0LL
                   : accumulate(v.begin() + 1, v.end(), v[0],
                                static_cast<i64 (*)(i64, i64)>(lcm));
}
i64 pow(i64 x, i64 y, i64 z) {
  i64 a = 1;
  while (y > 0) {
    if (y & 1)
      a = a * x % z;
    x = x * x % z;
    y /= 2;
  }
  return a;
}
i64 inv(i64 x, i64 m) { return pow(x, m - 2, m); }

struct InitCpp {
  InitCpp() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
  }
} initCpp;

const i64 INF = inf<i64>;
using P = pair<i64, i64>;
using T = pair<i64, P>;
const i64 M = 1000000007;
signed main() {
  i64 N, M;
  cin >> N >> M;
  vector<i64> A(N);
  cin >> A;
  sort(ALL(A));
  vector<i64> S(N + 1);
  REP(i, N) S[i + 1] = S[i] + A[i];
  i64 h_ng = 0;
  i64 h_ok = A[N - 1] * 2 + 2;
  i64 h = h_ok;
  i64 s = 0;
  i64 q = 0;
  i64 r = 0;
  i64 ans = 0;
  while (h_ok > h_ng + 1) {
    h = (h_ok + h_ng) / 2;
    s = 0;
    q = 0;
    r = 0;
    REP(i, N) {
      i64 ge = lower_bound(ALL(A), h - A[i]) - A.begin();
      i64 gt = upper_bound(ALL(A), h - A[i]) - A.begin();
      q += N - gt;
      r += gt - ge;
      s += S[N] - S[gt] + A[i] * (N - gt);
    }
    if (q <= M) {
      h_ok = h;
      if (M <= q + r) {
        cout << (s + (M - q) * h) << endl;
        exit(0);
      }
    } else {
      h_ng = h;
    }
  }
  exit(1);
}