Problem p03357 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define EPS (1e-10)
#define MOD 1000000007
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

int bit[2][200000];
void add(int t, int k, int x) {
  while (k < 200000) {
    bit[t][k] += x;
    k += k & -k;
  }
}
int sum(int t, int k) {
  int res = 0;
  while (k) {
    res += bit[t][k];
    k -= k & -k;
  }
  return res;
}

vector<int> dat[2][50000];
int p[2][5000];

void init(int t, int k, int l, int r) {
  if (r - l == 1) {
    dat[t][k].push_back(p[t][l]);
    return;
  }
  int lb = k * 2 + 1, rb = k * 2 + 2;
  init(t, lb, l, (l + r) / 2);
  init(t, rb, (l + r) / 2, r);
  dat[t][k].resize(r - l);
  merge(dat[t][lb].begin(), dat[t][lb].end(), dat[t][rb].begin(),
        dat[t][rb].end(), dat[t][k].begin());
}
int query(int t, int a, int b, int c, int d, int k, int l,
          int r) { //[a,b),[c,d)
  if (b <= l || r <= a)
    return 0;
  if (a <= l && r <= b) {
    int u =
        lower_bound(dat[t][k].begin(), dat[t][k].end(), d) - dat[t][k].begin();
    int v =
        lower_bound(dat[t][k].begin(), dat[t][k].end(), c) - dat[t][k].begin();
    return u - v;
  }
  int lb = query(t, a, b, c, d, k * 2 + 1, l, (l + r) / 2);
  int rb = query(t, a, b, c, d, k * 2 + 2, (l + r) / 2, r);
  return lb + rb;
}

string c[3000];
int a[3000];
ll dp[3000][3000];

signed main() {
  int n;
  scanf("%d", &n);
  rep(i, 2 * n) {
    cin >> c[i] >> a[i];
    a[i]--;
    if (c[i] == "B") {
      p[0][a[i]] = i;
    } else {
      p[1][a[i]] = i;
    }
  }
  ll ans = 0;
  int c1 = 0, c2 = 0;
  rep(i, 2 * n) {
    if (c[i] == "B") {
      ans += c1 - sum(0, a[i] + 1);
      c1++;
      add(0, a[i] + 1, 1);
    } else {
      ans += c2 - sum(1, a[i] + 1);
      c2++;
      add(1, a[i] + 1, 1);
    }
  }
  int N = 1;
  while (N < n)
    N <<= 1;
  rep(i, 2) init(i, 0, 0, N);
  memset(dp, 0x3f, sizeof(dp));
  dp[0][0] = 0;
  rep(i, n + 1) rep(j, n + 1) {
    if (i < n) {
      dp[i + 1][j] =
          min(dp[i + 1][j], dp[i][j] + query(1, 0, j, p[0][i], INF, 0, 0, N));
    }
    if (j < n) {
      dp[i][j + 1] =
          min(dp[i][j + 1], dp[i][j] + query(0, 0, i, p[1][j], INF, 0, 0, N));
    }
  }
  // for(int i=1;i<=n;i++)cout<<p[1][i]<<' ';
  // cout<<endl;
  /*rep(i,n+1){
          rep(j,n+1)cout<<dp[i][j]<<' ';
          cout<<endl;
  }*/
  cout << dp[n][n] + ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define EPS (1e-10)
#define MOD 1000000007
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

int bit[2][200000];
void add(int t, int k, int x) {
  while (k < 200000) {
    bit[t][k] += x;
    k += k & -k;
  }
}
int sum(int t, int k) {
  int res = 0;
  while (k) {
    res += bit[t][k];
    k -= k & -k;
  }
  return res;
}

vector<int> dat[2][50000];
int p[2][5000];

void init(int t, int k, int l, int r) {
  if (r - l == 1) {
    dat[t][k].push_back(p[t][l]);
    return;
  }
  int lb = k * 2 + 1, rb = k * 2 + 2;
  init(t, lb, l, (l + r) / 2);
  init(t, rb, (l + r) / 2, r);
  dat[t][k].resize(r - l);
  merge(dat[t][lb].begin(), dat[t][lb].end(), dat[t][rb].begin(),
        dat[t][rb].end(), dat[t][k].begin());
}
int query(int t, int a, int b, int c, int d, int k, int l,
          int r) { //[a,b),[c,d)
  if (b <= l || r <= a)
    return 0;
  if (a <= l && r <= b) {
    int u =
        lower_bound(dat[t][k].begin(), dat[t][k].end(), d) - dat[t][k].begin();
    int v =
        lower_bound(dat[t][k].begin(), dat[t][k].end(), c) - dat[t][k].begin();
    return u - v;
  }
  int lb = query(t, a, b, c, d, k * 2 + 1, l, (l + r) / 2);
  int rb = query(t, a, b, c, d, k * 2 + 2, (l + r) / 2, r);
  return lb + rb;
}

string c[5000];
int a[5000];
ll dp[3000][3000];

signed main() {
  int n;
  scanf("%d", &n);
  rep(i, 2 * n) {
    cin >> c[i] >> a[i];
    a[i]--;
    if (c[i] == "B") {
      p[0][a[i]] = i;
    } else {
      p[1][a[i]] = i;
    }
  }
  ll ans = 0;
  int c1 = 0, c2 = 0;
  rep(i, 2 * n) {
    if (c[i] == "B") {
      ans += c1 - sum(0, a[i] + 1);
      c1++;
      add(0, a[i] + 1, 1);
    } else {
      ans += c2 - sum(1, a[i] + 1);
      c2++;
      add(1, a[i] + 1, 1);
    }
  }
  int N = 1;
  while (N < n)
    N <<= 1;
  rep(i, 2) init(i, 0, 0, N);
  memset(dp, 0x3f, sizeof(dp));
  dp[0][0] = 0;
  rep(i, n + 1) rep(j, n + 1) {
    if (i < n) {
      dp[i + 1][j] =
          min(dp[i + 1][j], dp[i][j] + query(1, 0, j, p[0][i], INF, 0, 0, N));
    }
    if (j < n) {
      dp[i][j + 1] =
          min(dp[i][j + 1], dp[i][j] + query(0, 0, i, p[1][j], INF, 0, 0, N));
    }
  }
  // for(int i=1;i<=n;i++)cout<<p[1][i]<<' ';
  // cout<<endl;
  /*rep(i,n+1){
          rep(j,n+1)cout<<dp[i][j]<<' ';
          cout<<endl;
  }*/
  cout << dp[n][n] + ans << endl;
}