Problem p03483 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define rep2(i, x, n) for (int i = x; i <= n; i++)
#define rep3(i, x, n) for (int i = x; i >= n; i--)
#define elif else if
#define sp setprecision
#define pb(x) push_back(x)
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<int, ll> pil;
typedef pair<ll, int> pli;
typedef pair<ld, ld> pdd;
const ll MOD = 1e9 + 7;
// const ll MOD = 998244353;
const int inf = 1e8;
const ll INF = 1e16;
const string alpha = "abcdefghijklmnopqrstuvwxyz";

const int MAX_V = 2e5;

struct binary_indexed_tree {
  ll n, bit[MAX_V + 1];
  // 要素数N(0〜N-1)のBITを構築
  binary_indexed_tree(int N) {
    n = 1;
    while (n < N)
      n *= 2;
    fill_n(bit, n + 1, 0);
  }
  // i番目(0から数える)の要素にx加える
  void add(int i, ll x) {
    i++;
    while (i <= n) {
      bit[i] += x;
      i += (i & -i);
    }
  }
  // sum(i)で[0,i)の和を取得
  ll sum(int i) {
    ll s = 0;
    while (i > 0) {
      s += bit[i];
      i -= (i & -i);
    }
    return s;
  }
  // query(l,r)で[l,r)の和を取得
  ll query(int l, int r) { return sum(r) - sum(l); }
};

int main() {
  // 英小文字を整数に対応させる
  map<char, int> ctoi;
  rep(i, 26) ctoi[alpha[i]] = i;
  string S;
  cin >> S;
  int N = S.size();
  // 各アルファベットの最初のインデックスを記録
  vector<int> id[26];
  rep(i, N) id[ctoi[S[i]]].pb(i);
  // 奇数個出現する英小文字の数
  int cnt = 0;
  // 相方の初期位置
  int p[N];
  rep(i, 26) {
    int n = id[i].size();
    if (n % 2 == 1)
      cnt++;
    rep(j, n) { p[id[i][j]] = id[i][n - 1 - j]; }
  }
  if (cnt >= 2) {
    cout << -1 << endl;
    exit(0);
  }
  // 最初i番目だった文字が最終的に何文字目になるか
  int l[N];
  int now = 0;
  rep(i, N) {
    if (p[i] == i)
      l[i] = N / 2;
    elif (p[i] > i) {
      l[i] = now;
      now++;
    }
    else l[i] = N - 1 - l[p[i]];
  }
  // 数列lの転倒数が答え
  ll ans = 0;
  binary_indexed_tree bit(N);
  rep(i, N) {
    ans += bit.query(l[i], N);
    bit.add(l[i], 1);
  }
  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define rep2(i, x, n) for (int i = x; i <= n; i++)
#define rep3(i, x, n) for (int i = x; i >= n; i--)
#define elif else if
#define sp setprecision
#define pb(x) push_back(x)
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<int, ll> pil;
typedef pair<ll, int> pli;
typedef pair<ld, ld> pdd;
const ll MOD = 1e9 + 7;
// const ll MOD = 998244353;
const int inf = 1e8;
const ll INF = 1e16;
const string alpha = "abcdefghijklmnopqrstuvwxyz";

const int MAX_V = 5e5;

struct binary_indexed_tree {
  ll n, bit[MAX_V + 1];
  // 要素数N(0〜N-1)のBITを構築
  binary_indexed_tree(int N) {
    n = 1;
    while (n < N)
      n *= 2;
    fill_n(bit, n + 1, 0);
  }
  // i番目(0から数える)の要素にx加える
  void add(int i, ll x) {
    i++;
    while (i <= n) {
      bit[i] += x;
      i += (i & -i);
    }
  }
  // sum(i)で[0,i)の和を取得
  ll sum(int i) {
    ll s = 0;
    while (i > 0) {
      s += bit[i];
      i -= (i & -i);
    }
    return s;
  }
  // query(l,r)で[l,r)の和を取得
  ll query(int l, int r) { return sum(r) - sum(l); }
};

int main() {
  // 英小文字を整数に対応させる
  map<char, int> ctoi;
  rep(i, 26) ctoi[alpha[i]] = i;
  string S;
  cin >> S;
  int N = S.size();
  // 各アルファベットの最初のインデックスを記録
  vector<int> id[26];
  rep(i, N) id[ctoi[S[i]]].pb(i);
  // 奇数個出現する英小文字の数
  int cnt = 0;
  // 相方の初期位置
  int p[N];
  rep(i, 26) {
    int n = id[i].size();
    if (n % 2 == 1)
      cnt++;
    rep(j, n) { p[id[i][j]] = id[i][n - 1 - j]; }
  }
  if (cnt >= 2) {
    cout << -1 << endl;
    exit(0);
  }
  // 最初i番目だった文字が最終的に何文字目になるか
  int l[N];
  int now = 0;
  rep(i, N) {
    if (p[i] == i)
      l[i] = N / 2;
    elif (p[i] > i) {
      l[i] = now;
      now++;
    }
    else l[i] = N - 1 - l[p[i]];
  }
  // 数列lの転倒数が答え
  ll ans = 0;
  binary_indexed_tree bit(N);
  rep(i, N) {
    ans += bit.query(l[i], N);
    bit.add(l[i], 1);
  }
  cout << ans << endl;
}