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

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

class Bit {
  int n;
  vector<int> data;

public:
  Bit() {}
  Bit(int n) { // コンストラクタ
    this->n = n;
    data.assign(n + 1, 0);
  }
  void add(int k, int x) { // k番目の要素にxを加算する
    ++k;
    while (k <= n) {
      data[k] += x;
      k += k & -k;
    }
  }
  int sum(int k) { // 区間[0,k]の総和を返す
    ++k;
    int ret = 0;
    while (k > 0) {
      ret += data[k];
      k -= k & -k;
    }
    return ret;
  }
  int sum(int a, int b) { // 区間[a,b]の総和を返す
    return sum(b) - sum(a - 1);
  }
  int upper_bound(
      int x) { // 総和が初めてxを超える位置を返す（ただし、各位置の数値が非負数であることを前提とする）
    int b = 1;
    while (b < n)
      b *= 2;
    int a = 0;
    while (b > 0) {
      if (a + b <= n && x >= data[a + b]) {
        x -= data[a + b];
        a += b;
      }
      b /= 2;
    }
    return (a < n) ? a : -1;
  }
  int lower_bound(
      int x) { // 総和が初めてx以上になる位置を返す（ただし、各位置の数値が非負数であることを前提とする）
    return upper_bound(x - 1);
  }
};

int lim;
vector<int> n;
map<int, int> m;
Bit b;

void eraseNode(int t) {
  m.erase(n[t]);
  b.add(t, -1);
  ++lim;
}

void addNode(int x, int t) {
  n[t] = x;
  m[x] = t;
  b.add(t, 1);
  --lim;
  if (lim < 0)
    eraseNode(b.lower_bound(1));
}

int main() {
  for (;;) {
    int q;
    cin >> q >> lim;
    if (q == 0)
      return 0;

    n.assign(q, -1);
    m.clear();
    b = Bit(q);

    for (int t = 0; t < q; ++t) {
      int query, x;
      cin >> query >> x;
      if (query == 0) {
        addNode(x, t);
      } else if (query == 1) {
        int y = b.lower_bound(x);
        eraseNode(y);
      } else if (query == 2) {
        int y = b.lower_bound(x);
        cout << n[y] << endl;
      } else {
        eraseNode(m[x]);
      }
    }

    cout << "end" << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

class Bit {
  int n;
  vector<int> data;

public:
  Bit() {}
  Bit(int n) { // コンストラクタ
    this->n = n;
    data.assign(n + 1, 0);
  }
  void add(int k, int x) { // k番目の要素にxを加算する
    ++k;
    while (k <= n) {
      data[k] += x;
      k += k & -k;
    }
  }
  int sum(int k) { // 区間[0,k]の総和を返す
    ++k;
    int ret = 0;
    while (k > 0) {
      ret += data[k];
      k -= k & -k;
    }
    return ret;
  }
  int sum(int a, int b) { // 区間[a,b]の総和を返す
    return sum(b) - sum(a - 1);
  }
  int upper_bound(
      int x) { // 総和が初めてxを超える位置を返す（ただし、各位置の数値が非負数であることを前提とする）
    int b = 1;
    while (b < n)
      b *= 2;
    int a = 0;
    while (b > 0) {
      if (a + b <= n && x >= data[a + b]) {
        x -= data[a + b];
        a += b;
      }
      b /= 2;
    }
    return (a < n) ? a : -1;
  }
  int lower_bound(
      int x) { // 総和が初めてx以上になる位置を返す（ただし、各位置の数値が非負数であることを前提とする）
    return upper_bound(x - 1);
  }
};

int lim;
list<pair<int, int>> a;
map<int, list<pair<int, int>>::iterator> s; // 個体番号に対応するノード
map<int, list<pair<int, int>>::iterator> t; // 入力された時間に対応するノード
Bit b;

void eraseNode(list<pair<int, int>>::iterator it) {
  b.add(it->second, -1);
  a.erase(it);
}

void addNode(int x, int time) {
  a.push_back(make_pair(x, time));
  if (a.size() > lim)
    eraseNode(a.begin());
  b.add(time, 1);
  s[x] = --a.end();
  t[time] = --a.end();
}

int main() {
  for (;;) {
    int q;
    cin >> q >> lim;
    if (q == 0)
      return 0;

    a.clear();
    s.clear();
    t.clear();
    b = Bit(q);

    int time = 0;
    while (--q >= 0) {
      int query, x;
      cin >> query >> x;
      if (query == 0) {
        addNode(x, time);
        ++time;
      } else if (query == 1) {
        int y = b.lower_bound(x);
        eraseNode(t[y]);
      } else if (query == 2) {
        int y = b.lower_bound(x);
        cout << t[y]->first << endl;
      } else {
        eraseNode(s[x]);
      }
    }

    cout << "end" << endl;
  }
}