Problem p02888 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <iostream>
using namespace std;
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#define MOD1 1000000007
#define MOD2 998244353
#define LIMIT1 200002
#define LIMIT2 500002
typedef long long ll;
typedef long double ld;
typedef const void cv;
#define rep(i, n) for ((i) = 0; (i) < (n); (i)++)
#define per(i, n) for ((i) = (n)-1; (i) >= 0; (i)--)
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define zt(a, b) (max((a), (b)) - min((a), (b)))
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll nPr(int n, int r) {
  ll i, result = 1;
  rep(i, r) { result *= (ll)(n - i); }
  return result;
}
ll nCr(int n, int r) {
  ll i, result = 1;
  if (n < r)
    return 0;
  rep(i, min(r, n - r)) {
    result *= (ll)(n - i);
    result /= (ll)(i + 1);
  }
  return result;
}
#define nHr(n, r) nCr((int)((n) + (r) + 1), (int)(r))
#define sankaku(x) (((x) * ((x) + 1)) / 2)
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1}, dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
int upint(cv *a, cv *b) {
  return *(int *)a < *(int *)b ? -1 : *(int *)a > *(int *)b ? 1 : 0;
}
int downint(cv *a, cv *b) {
  return *(int *)a < *(int *)b ? 1 : *(int *)a > *(int *)b ? -1 : 0;
}
int upchar(cv *left, cv *right) { return strcmp((char *)left, (char *)right); }
int downchar(cv *left, cv *right) {
  return strcmp((char *)right, (char *)left);
}
void tmpInit(int *c, ll m) {
  ll i;
  rep(i, m) c[i] = i;
}
ll modpow(ll a, ll n, ll mod) {
  ll res = 1;
  while (n > 0) {
    if (n & 1) {
      res *= a;
      if (mod >= 1)
        res %= mod;
    }
    a *= a;
    if (mod >= 1)
      a %= mod;
    n >>= 1;
  }
  return res;
}
void initialize() {}
int a[LIMIT2] = {0};
ll findData(ll i) {
  // findDataが単調減少のときはbinaryの不等号を反転させる
  if (i == -1)
    return -1;
  return (ll)a[i];
}
ll binaryCeil(ll max, ll min, ll target) {
  // targetの数値以上の最小
  ll mid;
  ll count = 0;
  while (max > min && count < 1000) {
    mid = (max + min) / 2;
    if (findData(mid) >= target)
      max = mid;
    else
      min = mid + 1;
    count++;
  }
  return max;
}
int main(void) {
  initialize();
  ll n, m, i, j, k, result = 0;
  char s[LIMIT1];

  cin >> n;
  rep(i, n) { cin >> a[i]; }
  qsort(a, n, sizeof(int), upint);

  for (i = n - 1; i >= 2; i--) {
    for (j = i - 1; j >= 1; j--) {
      k = binaryCeil((ll)j, -1, (ll)(a[i] - a[j] + 1));
      // cout << k << endl;
      result += j - k;
    }
  }
  cout << result << endl;
  return 0;
}

Fixed submission:
#include <iostream>
using namespace std;
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#define MOD1 1000000007
#define MOD2 998244353
#define LIMIT1 200002
#define LIMIT2 500002
typedef long long ll;
typedef long double ld;
typedef const void cv;
#define rep(i, n) for ((i) = 0; (i) < (n); (i)++)
#define per(i, n) for ((i) = (n)-1; (i) >= 0; (i)--)
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define zt(a, b) (max((a), (b)) - min((a), (b)))
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll nPr(int n, int r) {
  ll i, result = 1;
  rep(i, r) { result *= (ll)(n - i); }
  return result;
}
ll nCr(int n, int r) {
  ll i, result = 1;
  if (n < r)
    return 0;
  rep(i, min(r, n - r)) {
    result *= (ll)(n - i);
    result /= (ll)(i + 1);
  }
  return result;
}
#define nHr(n, r) nCr((int)((n) + (r) + 1), (int)(r))
#define sankaku(x) (((x) * ((x) + 1)) / 2)
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1}, dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
int upint(cv *a, cv *b) {
  return *(int *)a < *(int *)b ? -1 : *(int *)a > *(int *)b ? 1 : 0;
}
int downint(cv *a, cv *b) {
  return *(int *)a < *(int *)b ? 1 : *(int *)a > *(int *)b ? -1 : 0;
}
int upchar(cv *left, cv *right) { return strcmp((char *)left, (char *)right); }
int downchar(cv *left, cv *right) {
  return strcmp((char *)right, (char *)left);
}
void tmpInit(int *c, ll m) {
  ll i;
  rep(i, m) c[i] = i;
}
ll modpow(ll a, ll n, ll mod) {
  ll res = 1;
  while (n > 0) {
    if (n & 1) {
      res *= a;
      if (mod >= 1)
        res %= mod;
    }
    a *= a;
    if (mod >= 1)
      a %= mod;
    n >>= 1;
  }
  return res;
}
void initialize() {}
int a[LIMIT2] = {0};
ll findData(ll i) {
  // findDataが単調減少のときはbinaryの不等号を反転させる
  if (i == -1)
    return -1;
  return (ll)a[i];
}
ll binaryCeil(ll max, ll min, ll target) {
  // targetの数値以上の最小
  ll mid;
  ll count = 0;
  while (max > min && count < 100) {
    mid = (max + min) / 2;
    if (findData(mid) >= target)
      max = mid;
    else
      min = mid + 1;
    count++;
  }
  return max;
}
int main(void) {
  initialize();
  ll n, m, i, j, k, result = 0;
  char s[LIMIT1];

  cin >> n;
  rep(i, n) { cin >> a[i]; }
  qsort(a, n, sizeof(int), upint);

  for (i = n - 1; i >= 2; i--) {
    for (j = i - 1; j >= 1; j--) {
      k = binaryCeil((ll)j, -1, (ll)(a[i] - a[j] + 1));
      // cout << k << endl;
      result += j - k;
    }
  }
  cout << result << endl;
  return 0;
}