Problem p00668 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
static const double EPS = 1e-8;
static const double PI = 4.0 * atan(1.0);
bool ISINT(double x) { return fabs(x - (int)x) < EPS; }
bool ISEQ(double x, double y) { return fabs(x - y) < EPS; }
string itos(ll x) {
  stringstream ss;
  ss << x;
  return ss.str();
}
#define REP(i, a, b) for (int i = a; i < b; i++)
#define rep(i, n) REP(i, 0, n)
#define EREP(i, a, b) for (int i = a; i <= b; i++)
#define erep(i, n) EREP(i, 0, n)
#define foreach(itr, c)                                                        \\
  for (__typeof(c.begin()) itr = c.begin(); itr != c.end(); itr++)

typedef pair<int, int> P;

int dat[1 << 20 + 2];
int low = 1 << 19 - 1;

int q, lim;
int size;
map<int, int> num;
int rnum[400000];

void add(int x) {
  num[x] = size;
  dat[size] = 0;
  rnum[size - low] = x;

  lim--;
  size++;

  int pos = size - 1;

  while (0 < pos) {
    dat[pos]++;
    pos = (pos - 1) / 2;
  }
}

int find(int x) {
  int pos = 0;

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

    if (x <= dat[left]) {
      pos = left;
    } else {
      x -= dat[left];
      pos = right;
    }
  }

  return pos;
}

void erase(int pos) {
  lim++;

  while (0 < pos) {
    dat[pos]--;
    pos = (pos - 1) / 2;
  }
}

int main(void) {
  while (scanf("%d%d", &q, &lim), q || lim) {
    memset(dat, 0, sizeof(dat));
    memset(rnum, 0, sizeof(rnum));
    num.clear();
    size = low;

    while (q--) {
      int query, x;
      scanf("%d%d", &query, &x);

      if (query == 0) {
        add(x);
        if (lim < 0) {
          int pos = find(0);
          erase(pos);
        }
      } else if (query == 1) {
        int pos = find(x);
        erase(pos);
      } else if (query == 2) {
        int pos = find(x);
        printf("%d\\n", rnum[pos - low]);
      } else if (query == 3) {
        int pos = num[x];
        erase(pos);
      }
    }

    printf("end\\n");
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
static const double EPS = 1e-8;
static const double PI = 4.0 * atan(1.0);
bool ISINT(double x) { return fabs(x - (int)x) < EPS; }
bool ISEQ(double x, double y) { return fabs(x - y) < EPS; }
string itos(ll x) {
  stringstream ss;
  ss << x;
  return ss.str();
}
#define REP(i, a, b) for (int i = a; i < b; i++)
#define rep(i, n) REP(i, 0, n)
#define EREP(i, a, b) for (int i = a; i <= b; i++)
#define erep(i, n) EREP(i, 0, n)
#define foreach(itr, c)                                                        \\
  for (__typeof(c.begin()) itr = c.begin(); itr != c.end(); itr++)

typedef pair<int, int> P;

P dat[1 << 20 + 2];
int low = 1 << 19 - 1;

int q, lim;
int size;
map<int, int> num;

void add(int x) {
  num[x] = size;
  dat[size] = P(0, x);

  lim--;
  size++;

  int pos = size - 1;

  while (0 < pos) {
    dat[pos].first++;
    pos = (pos - 1) / 2;
  }
}

int find(int x) {
  int pos = 0;

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

    if (x <= dat[left].first) {
      pos = left;
    } else {
      x -= dat[left].first;
      pos = right;
    }

    // cout<<":"<<pos<<endl;
  }

  return pos;
}

void erase(int pos) {
  lim++;

  while (0 < pos) {
    dat[pos].first--;
    pos = (pos - 1) / 2;
  }
}

int main(void) {
  while (scanf("%d%d", &q, &lim), q || lim) {
    memset(dat, 0, sizeof(dat));
    num.clear();
    size = low;

    while (q--) {
      int query, x;
      scanf("%d%d", &query, &x);

      if (query == 0) {
        add(x);
        if (lim < 0) {
          int pos = find(0);
          erase(pos);
        }
      } else if (query == 1) {
        int pos = find(x);
        erase(pos);
      } else if (query == 2) {
        int pos = find(x);
        // cout<<"pos : "<<pos<<endl;
        printf("%d\\n", dat[pos].second);
      } else if (query == 3) {
        int pos = num[x];
        erase(pos);
      }
    }

    /*
    foreach(i,num){
      cout<<(i->first)<<","<<(i->second)<<endl;
    }
    */

    printf("end\\n");
  }
}