Problem p03275 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> Pii;
typedef pair<ll, ll> Pll;
#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define rep2(i, a, b) for (ll i = (a); i < (b); ++i)
#define debug(x) cout << #x << '=' << x << endl
#define all(v) (v).begin(), (v).end()
const ll MOD = 1e9 + 7;
// const ll MOD=998244353;
const ll INF = 1e9;
const ll IINF = 1e18;
const double EPS = 1e-8;
const double pi = acos(-1);

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <typename T> struct BinaryIndexedTree {
private:
  vector<T> dat;

public:
  BinaryIndexedTree(int sz) { dat.assign(++sz, 0); }
  void add(int k, T x) {
    for (; k <= dat.size(); k += k & -k)
      dat[k] += x;
  }
  T sum(int k) {
    T ret = 0;
    for (; k > 0; k -= k & -k)
      ret += dat[k];
    return ret;
  }
  int lower_bound(T x) {
    if (x <= 0)
      return 0;
    int lb = 0, r = 1;
    while (r < dat.size())
      r <<= 1;
    for (; r > 0; r >>= 1) {
      if (lb + r < dat.size() && dat[lb + r] < x) {
        x -= dat[lb + r];
        lb += r;
      }
    }
    return lb + 1;
  }
  T query(int l, int r) { //[l,r)
    return sum(r - 1) - sum(l - 1);
  }
};

const ll MAX_N = 1e5 + 10;

ll N;
vector<ll> A(MAX_N);
vector<ll> sum(N + 1, -1);
vector<vector<ll>> sumid(2 * MAX_N);
ll minimum;

bool can(int n) {
  rep2(i, 1, N + 1) sum[i] = -1;
  sum[0] = 0;
  rep(i, N) if (A[i] <= n) sum[i + 1] = 1;
  rep(i, N) sum[i + 1] += sum[i];
  rep(i, 2 * MAX_N) sumid[i].clear();
  rep(i, N + 1) sumid[sum[i] + MAX_N].push_back(i);
  BinaryIndexedTree<ll> BIT(N + 1);
  ll cnt = 0;
  rep(i, 2 * MAX_N) {
    for (auto x : sumid[i])
      cnt += BIT.sum(x + 1);
    for (auto x : sumid[i])
      BIT.add(x + 1, 1);
  }
  if (cnt >= minimum)
    return true;
  return false;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> N;
  rep(i, N) cin >> A[i];
  minimum = N * (N + 1) / 2 / 2 + 1;
  ll lb = 0, ub = 1e9 + 1;
  while (ub - lb > 1) {
    ll mid = (ub + lb) / 2;
    if (can(mid))
      ub = mid;
    else
      lb = mid;
  }
  cout << ub << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> Pii;
typedef pair<ll, ll> Pll;
#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define rep2(i, a, b) for (ll i = (a); i < (b); ++i)
#define debug(x) cout << #x << '=' << x << endl
#define all(v) (v).begin(), (v).end()
const ll MOD = 1e9 + 7;
// const ll MOD=998244353;
const ll INF = 1e9;
const ll IINF = 1e18;
const double EPS = 1e-8;
const double pi = acos(-1);

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <typename T> struct BinaryIndexedTree {
private:
  vector<T> dat;

public:
  BinaryIndexedTree(int sz) { dat.assign(++sz, 0); }
  void add(int k, T x) {
    for (; k <= dat.size(); k += k & -k)
      dat[k] += x;
  }
  T sum(int k) {
    T ret = 0;
    for (; k > 0; k -= k & -k)
      ret += dat[k];
    return ret;
  }
  int lower_bound(T x) {
    if (x <= 0)
      return 0;
    int lb = 0, r = 1;
    while (r < dat.size())
      r <<= 1;
    for (; r > 0; r >>= 1) {
      if (lb + r < dat.size() && dat[lb + r] < x) {
        x -= dat[lb + r];
        lb += r;
      }
    }
    return lb + 1;
  }
  T query(int l, int r) { //[l,r)
    return sum(r - 1) - sum(l - 1);
  }
};

const ll MAX_N = 1e5 + 10;

ll N;
vector<ll> A(MAX_N);
vector<ll> sum(MAX_N, -1);
vector<vector<ll>> sumid(2 * MAX_N);
ll minimum;

bool can(int n) {
  rep2(i, 1, N + 1) sum[i] = -1;
  sum[0] = 0;
  rep(i, N) if (A[i] <= n) sum[i + 1] = 1;
  rep(i, N) sum[i + 1] += sum[i];
  rep(i, 2 * MAX_N) sumid[i].clear();
  rep(i, N + 1) sumid[sum[i] + MAX_N].push_back(i);
  BinaryIndexedTree<ll> BIT(N + 1);
  ll cnt = 0;
  rep(i, 2 * MAX_N) {
    for (auto x : sumid[i])
      cnt += BIT.sum(x + 1);
    for (auto x : sumid[i])
      BIT.add(x + 1, 1);
  }
  if (cnt >= minimum)
    return true;
  return false;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> N;
  rep(i, N) cin >> A[i];
  minimum = N * (N + 1) / 2 / 2 + 1;
  ll lb = 0, ub = 1e9 + 1;
  while (ub - lb > 1) {
    ll mid = (ub + lb) / 2;
    if (can(mid))
      ub = mid;
    else
      lb = mid;
  }
  cout << ub << endl;
}