Problem p03483 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <assert.h>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iostream>
#include <list>
#include <map>
#include <memory.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;
#define ll long long
#define pb push_back
#define fi(ss) freopen(ss, "r", stdin)
#define fo(ss) freopen(ss, "w", stdout)
#define sz(v) ((int)((v).size()))
#define all(x) (x).begin(), (x).end()
#define REP(i, v) for (int i = 0; i < sz(v); i++)
typedef pair<int, int> pii;
#define ios std::ios_base::sync_with_stdio(false);
using namespace std;
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>

const int N = 1000000;

int n;
char str[N + 1];
deque<int> letters[26];

int cnt[N];
bool present[N];

void add(int k, int v) {
  for (; k < n; k += ~k & k + 1) {
    cnt[k] += v;
  }
}

int respond(int k) {
  int ret = 0;
  for (; k >= 0; k -= ~k & k + 1) {
    ret += cnt[k];
  }
  return ret;
}

void erase(int i) {
  present[i] = false;
  add(i, -1);
}

int main() {
  scanf("%s", str);
  n = strlen(str);
  for (int i = 0; i < n; ++i) {
    letters[(int)(str[i] -= 'A')].push_back(i);
  }
  int odd_count = 0;
  for (int i = 0; i < 26; ++i) {
    odd_count += letters[i].size() & 1;
  }
  if (odd_count != (n & 1)) {
    puts("-1");
    return 0;
  }
  memset(present, true, sizeof(present));
  for (int i = 0; i < n; ++i) {
    add(i, 1);
  }
  long long answer = 0;
  for (int l = 0, r = n - 1; l < r;) {
    if (!present[l]) {
      l++;
    } else if (!present[r]) {
      r--;
    } else {

      int left_cost = respond(n - 1) - respond(letters[(int)str[l]].back());
      int right_cost = respond(letters[(int)str[r]].front()) - 1;
      answer += std::min(left_cost, right_cost);
      int token = left_cost < right_cost ? str[l] : str[r];
      erase(letters[token].front());
      erase(letters[token].back());
      letters[token].pop_front();
      letters[token].pop_back();
    }
  }
  cout << answer << "\n";
  return 0;
}


Fixed submission:
#include <algorithm>
#include <assert.h>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iostream>
#include <list>
#include <map>
#include <memory.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;
#define ll long long
#define pb push_back
#define fi(ss) freopen(ss, "r", stdin)
#define fo(ss) freopen(ss, "w", stdout)
#define sz(v) ((int)((v).size()))
#define all(x) (x).begin(), (x).end()
#define REP(i, v) for (int i = 0; i < sz(v); i++)
typedef pair<int, int> pii;
#define ios std::ios_base::sync_with_stdio(false);
using namespace std;
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>

const int N = 1000000;

int n;
char str[N + 1];
deque<int> letters[26];

int cnt[N];
bool present[N];

void add(int k, int v) {
  for (; k < n; k += ~k & k + 1) {
    cnt[k] += v;
  }
}

int respond(int k) {
  int ret = 0;
  for (; k >= 0; k -= ~k & k + 1) {
    ret += cnt[k];
  }
  return ret;
}

void erase(int i) {
  present[i] = false;
  add(i, -1);
}

int main() {
  scanf("%s", str);
  n = strlen(str);
  for (int i = 0; i < n; ++i) {
    letters[(int)(str[i] -= 'a')].push_back(i);
  }
  int odd_count = 0;
  for (int i = 0; i < 26; ++i) {
    odd_count += letters[i].size() & 1;
  }
  if (odd_count != (n & 1)) {
    puts("-1");
    return 0;
  }
  memset(present, true, sizeof(present));
  for (int i = 0; i < n; ++i) {
    add(i, 1);
  }
  long long answer = 0;
  for (int l = 0, r = n - 1; l < r;) {
    if (!present[l]) {
      l++;
    } else if (!present[r]) {
      r--;
    } else {

      int left_cost = respond(n - 1) - respond(letters[(int)str[l]].back());
      int right_cost = respond(letters[(int)str[r]].front()) - 1;
      answer += std::min(left_cost, right_cost);
      int token = left_cost < right_cost ? str[l] : str[r];
      erase(letters[token].front());
      erase(letters[token].back());
      letters[token].pop_front();
      letters[token].pop_back();
    }
  }
  cout << answer << "\n";
  return 0;
}