Problem p03483 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <cstdio>
#include <cstring>

const int MAXN = 2e5 + 5;
int n;
int a[MAXN];
char s[MAXN];

inline int chr_idx(char c) { return c - 'a'; }

template <class T> long long mge_sort(T a[], int l, int r) {
  static T tmp[MAXN];
  if (l == r)
    return 0;
  int mid = l + r >> 1;
  long long ret = mge_sort(a, l, mid) + mge_sort(a, mid + 1, r);
  int lp = l, rp = mid + 1, cur = l - 1;
  while (lp <= mid && rp <= r) {
    if (a[lp] <= a[rp])
      tmp[++cur] = a[lp++];
    else {
      ret += mid - lp + 1;
      tmp[++cur] = a[rp++];
    }
  }
  while (lp <= mid)
    tmp[++cur] = a[lp++];
  while (rp <= r)
    tmp[++cur] = a[rp++];
  memcpy(a + l, tmp + l, (r - l + 1) * sizeof(T));
  return ret;
}

inline void deal() {
  static int pos[26], pre[MAXN], nex[MAXN];
  static bool use[MAXN];
  for (int i = n; i; --i) {
    nex[i] = pos[chr_idx(s[i])];
    pos[chr_idx(s[i])] = i;
  }
  for (int i = 1; i <= n; ++i) {
    pre[i] = pos[chr_idx(s[i])];
    pos[chr_idx(s[i])] = i;
  }
  for (int i = 1, x, y; i <= n; ++i) {
    if (use[i])
      continue;
    x = i, y = pos[chr_idx(s[i])];
    while (y) {
      a[n - x + 1] = y;
      use[x] = true;
      x = nex[x], y = pre[y];
    }
  }
}

inline bool spj() {
  static int cnt[26];
  for (int i = 1; i <= n; ++i)
    ++cnt[chr_idx(s[i])];
  int tot = 0;
  for (int i = 0; i < 26; ++i) {
    if (cnt[i] & 1)
      ++tot;
  }
  return tot == (n & 1);
}

int main() {
  scanf("%s", s + 1);
  n = strlen(s + 1);
  if (!spj()) {
    printf("-1");
    return 0;
  }
  deal();
  printf("%lld", mge_sort(a, 1, n) >> 1);
  return 0;
}

Fixed submission:
#include <cstdio>
#include <cstring>

const int MAXN = 2e5 + 5;
int n;
int a[MAXN];
char s[MAXN];

inline int chr_idx(char c) { return c - 'a'; }

template <class T> long long mge_sort(T a[], int l, int r) {
  static T tmp[MAXN];
  if (l == r)
    return 0;
  int mid = l + r >> 1;
  long long ret = mge_sort(a, l, mid) + mge_sort(a, mid + 1, r);
  int lp = l, rp = mid + 1, cur = l - 1;
  while (lp <= mid && rp <= r) {
    if (a[lp] <= a[rp])
      tmp[++cur] = a[lp++];
    else {
      ret += mid - lp + 1;
      tmp[++cur] = a[rp++];
    }
  }
  while (lp <= mid)
    tmp[++cur] = a[lp++];
  while (rp <= r)
    tmp[++cur] = a[rp++];
  memcpy(a + l, tmp + l, (r - l + 1) * sizeof(T));
  return ret;
}

inline void deal() {
  static int pos[26], pre[MAXN], nex[MAXN];
  static bool use[MAXN];
  for (int i = n; i; --i) {
    nex[i] = pos[chr_idx(s[i])];
    pos[chr_idx(s[i])] = i;
  }
  memset(pos, 0, sizeof(pos));
  for (int i = 1; i <= n; ++i) {
    pre[i] = pos[chr_idx(s[i])];
    pos[chr_idx(s[i])] = i;
  }
  for (int i = 1, x, y; i <= n; ++i) {
    if (use[i])
      continue;
    x = i, y = pos[chr_idx(s[i])];
    while (y) {
      a[n - x + 1] = y;
      use[x] = true;
      x = nex[x], y = pre[y];
    }
  }
}

inline bool spj() {
  static int cnt[26];
  for (int i = 1; i <= n; ++i)
    ++cnt[chr_idx(s[i])];
  int tot = 0;
  for (int i = 0; i < 26; ++i) {
    if (cnt[i] & 1)
      ++tot;
  }
  return tot == (n & 1);
}

int main() {
  scanf("%s", s + 1);
  n = strlen(s + 1);
  if (!spj()) {
    printf("-1");
    return 0;
  }
  deal();
  printf("%lld", mge_sort(a, 1, n) >> 1);
  return 0;
}