Problem p03483 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 1e9;

template <typename T> struct BinaryIndexedTree {
  vector<T> dat;
  BinaryIndexedTree(int n) : dat(n + 1, 0) {}
  void add(int i, T x) {
    if (i == 0)
      return;
    for (; i <= dat.size(); i += (i & -i))
      dat[i] += x;
  }
  T sum(int i) {
    T res = 0;
    for (; i > 0; i -= (i & -i))
      res += dat[i];
    return res;
  }
  T query(int l, int r) { //[l,r)
    return sum(r - 1) - sum(l - 1);
  }
  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;
  }
  void add0(int i, T x) { add(i + 1, x); }
  T sum0(int i) { return sum(i + 1); }
  T query0(int l, int r) { return sum(r) - sum(l); }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  string S;
  cin >> S;
  int n = S.size();
  vector<vector<int>> pos(26);
  for (int i = 0; i < n; ++i)
    pos[S[i] - 'a'].emplace_back(i);
  int odd = 0;
  vector<queue<pair<int, int>>> que(26);
  for (int i = 0; i < 26; ++i) {
    int s = pos[i].size();
    odd += s & 1;
    for (int j = 0; j < s - 1 - j; ++j)
      que[i].emplace(pos[i][j], pos[i][s - 1 - j]);
  }
  if (odd != (n & 1)) {
    cout << -1 << '\n';
    return 0;
  }
  BinaryIndexedTree<int> BIT(n + 1);
  for (int i = 0; i < n; ++i)
    BIT.add0(i, 1);
  ll ans = 0;
  for (int i = 0; i < n / 2; ++i) {
    int Min = INF, nxt;
    for (int j = 0; j < 26; ++j) {
      auto p = que[j].front();
      if (BIT.query0(0, p.first) + BIT.query0(p.second + 1, n) < Min) {
        Min = BIT.query0(0, p.first) + BIT.query0(p.second + 1, n);
        nxt = j;
      }
    }
    ans += Min;
    auto p = que[nxt].front();
    que[nxt].pop();
    BIT.add0(p.first, -1);
    BIT.add0(p.second, -1);
  }
  cout << ans << '\n';
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 1e9;

template <typename T> struct BinaryIndexedTree {
  vector<T> dat;
  BinaryIndexedTree(int n) : dat(n + 1, 0) {}
  void add(int i, T x) {
    if (i == 0)
      return;
    for (; i <= dat.size(); i += (i & -i))
      dat[i] += x;
  }
  T sum(int i) {
    T res = 0;
    for (; i > 0; i -= (i & -i))
      res += dat[i];
    return res;
  }
  T query(int l, int r) { //[l,r)
    return sum(r - 1) - sum(l - 1);
  }
  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;
  }
  void add0(int i, T x) { add(i + 1, x); }
  T sum0(int i) { return sum(i + 1); }
  T query0(int l, int r) { return sum(r) - sum(l); }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  string S;
  cin >> S;
  int n = S.size();
  vector<vector<int>> pos(26);
  for (int i = 0; i < n; ++i)
    pos[S[i] - 'a'].emplace_back(i);
  int odd = 0;
  vector<queue<pair<int, int>>> que(26);
  for (int i = 0; i < 26; ++i) {
    int s = pos[i].size();
    odd += s & 1;
    for (int j = 0; j < s - 1 - j; ++j)
      que[i].emplace(pos[i][j], pos[i][s - 1 - j]);
  }
  if (odd != (n & 1)) {
    cout << -1 << '\n';
    return 0;
  }
  BinaryIndexedTree<int> BIT(n + 1);
  for (int i = 0; i < n; ++i)
    BIT.add0(i, 1);
  ll ans = 0;
  for (int i = 0; i < n / 2; ++i) {
    int Min = INF, nxt;
    for (int j = 0; j < 26; ++j) {
      if (que[j].empty())
        continue;
      auto p = que[j].front();
      if (BIT.query0(0, p.first) + BIT.query0(p.second + 1, n) < Min) {
        Min = BIT.query0(0, p.first) + BIT.query0(p.second + 1, n);
        nxt = j;
      }
    }
    ans += Min;
    auto p = que[nxt].front();
    que[nxt].pop();
    BIT.add0(p.first, -1);
    BIT.add0(p.second, -1);
  }
  cout << ans << '\n';
}