Problem p00668 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define f first
#define s second
#define mp make_pair

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define rep(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOR(i, c)                                                              \
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define ALL(c) (c).begin(), (c).end()
#define IN(x, s, g) ((x) >= (s) && (x) < (g))
#define ISIN(x, y, w, h) (IN((x), 0, (w)) && IN((y), 0, (h)))
#define print(x) printf("%d\n", x)

using namespace std;

typedef unsigned int uint;
typedef long long ll;

const int _dx[] = {0, 1, 0, -1};
const int _dy[] = {-1, 0, 1, 0};

int getInt() {
  int ret = 0, c;
  c = getchar();
  while (!isdigit(c))
    c = getchar();
  while (isdigit(c)) {
    ret *= 10;
    ret += c - '0';
    c = getchar();
  }
  return ret;
}

const int MAX = 64 * 1024;
int id[MAX];
int idCnt;
int segTree[MAX * 2];
map<int, int> dict;

int q;
int lim;

void init() {
  idCnt = 0;
  memset(segTree, 0, sizeof(segTree));
  dict.clear();
}

void update(int pos, int val) {
  pos += MAX;
  segTree[pos] = val;
  while (pos) {
    pos = (pos - 1) / 2;
    segTree[pos] = segTree[2 * pos + 1] + segTree[2 * pos + 2];
  }
}

int nthId(int n) {
  int pos = 0;

  n += 1;

  while (pos < MAX) {
    int left = pos * 2 + 1;
    int right = pos * 2 + 2;

    // printf("n=%d l=%d r=%d\n", n, segTree[left], segTree[right]);

    if (segTree[left] >= n) {
      pos = left;
    } else {
      pos = right;
      n -= segTree[left];
    }
  }

  if (n != 1 || segTree[pos] != 1) {
    printf("error: n=%d segTree[%d]=%d %d\n", n, pos, segTree[pos], pos - MAX);
  }

  return pos - MAX;
}

void delId(int i) { update(nthId(i), 0); }

void delVal(int i) { update(dict[i], 0); }

void addId(int i) {
  id[idCnt] = i;
  dict[i] = idCnt;
  update(idCnt, 1);
  if (segTree[0] > lim)
    delId(0);
  idCnt++;
}

int main() {
  while (true) {
    q = getInt();
    lim = getInt();

    if (q == 0)
      break;

    init();

    while (q-- > 0) {
      int query = getInt();
      int x = getInt();

      switch (query) {
      case 0:
        addId(x);
        break;
      case 1:
        delId(x - 1);
        break;
      case 2:
        printf("%d\n", id[nthId(x - 1)]);
        break;
      case 3:
        delVal(x);
        break;
      }

      // printf("query: %d %d\n", query, x);
      // printf("alive: %d\n", segTree[0]);
      // REP(i, idCnt) printf("%d(%d) ", id[i], segTree[i+MAX]); puts("");
    }

    puts("end");
  }

  return 0;
}

Fixed submission:
#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define f first
#define s second
#define mp make_pair

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define rep(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOR(i, c)                                                              \
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define ALL(c) (c).begin(), (c).end()
#define IN(x, s, g) ((x) >= (s) && (x) < (g))
#define ISIN(x, y, w, h) (IN((x), 0, (w)) && IN((y), 0, (h)))
#define print(x) printf("%d\n", x)

using namespace std;

typedef unsigned int uint;
typedef long long ll;

const int _dx[] = {0, 1, 0, -1};
const int _dy[] = {-1, 0, 1, 0};

int getInt() {
  int ret = 0, c;
  c = getchar();
  while (!isdigit(c))
    c = getchar();
  while (isdigit(c)) {
    ret *= 10;
    ret += c - '0';
    c = getchar();
  }
  return ret;
}

const int MAX = 16 * 64 * 1024;
int id[MAX];
int idCnt;
int segTree[MAX * 2];
map<int, int> dict;

int q;
int lim;

void init() {
  idCnt = 0;
  memset(segTree, 0, sizeof(segTree));
  dict.clear();
}

void update(int pos, int val) {
  pos += MAX;
  segTree[pos] = val;
  while (pos) {
    pos = (pos - 1) / 2;
    segTree[pos] = segTree[2 * pos + 1] + segTree[2 * pos + 2];
  }
}

int nthId(int n) {
  int pos = 0;

  n += 1;

  while (pos < MAX) {
    int left = pos * 2 + 1;
    int right = pos * 2 + 2;

    // printf("n=%d l=%d r=%d\n", n, segTree[left], segTree[right]);

    if (segTree[left] >= n) {
      pos = left;
    } else {
      pos = right;
      n -= segTree[left];
    }
  }

  if (n != 1 || segTree[pos] != 1) {
    printf("error: n=%d segTree[%d]=%d %d\n", n, pos, segTree[pos], pos - MAX);
  }

  return pos - MAX;
}

void delId(int i) { update(nthId(i), 0); }

void delVal(int i) { update(dict[i], 0); }

void addId(int i) {
  id[idCnt] = i;
  dict[i] = idCnt;
  update(idCnt, 1);
  if (segTree[0] > lim)
    delId(0);
  idCnt++;
}

int main() {
  while (true) {
    q = getInt();
    lim = getInt();

    if (q == 0)
      break;

    init();

    while (q-- > 0) {
      int query = getInt();
      int x = getInt();

      switch (query) {
      case 0:
        addId(x);
        break;
      case 1:
        delId(x - 1);
        break;
      case 2:
        printf("%d\n", id[nthId(x - 1)]);
        break;
      case 3:
        delVal(x);
        break;
      }

      // printf("query: %d %d\n", query, x);
      // printf("alive: %d\n", segTree[0]);
      // REP(i, idCnt) printf("%d(%d) ", id[i], segTree[i+MAX]); puts("");
    }

    puts("end");
  }

  return 0;
}