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

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <iostream>
#include <queue>
#include <string>
#include <unordered_map>
#include <vector>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<int> VI;
typedef vector<ll> VL;
typedef pair<int, int> ipair;
typedef tuple<int, int, int> ituple;

// const int INF = INT_MAX;
// const ll INF = LLONG_MAX;
// const int MOD = ((int)1e9 + 7);
// const ld EPS = (1e-10);
#define PI acosl(-1)
#define MAX_N (500000)

class BitSum {
protected:
  static const int max_value = 500000 + 2;
  ll bit[max_value + 1];

public:
  BitSum(int size) {
    assert(size < max_value);
    init();
  }
  void init() {
    for (int i = 0; i < max_value; i++) {
      bit[i] = 0;
    }
  }
  void add(int idx, ll val) {
    int p = idx + 1;
    while (p < max_value) {
      bit[p] += val;
      p += p & -p;
    }
  }
  /**
   * [0, idx]のsumを求める
   */
  ll calc(int idx) {
    ll res = 0;
    int p = idx + 1;
    while (0 < p) {
      res += bit[p];
      p -= p & -p;
    }
    return res;
  }
  /**
   * [idx1, idx2]のsumを求める
   */
  ll range(int idx1, int idx2) { return calc(idx2) - calc(idx1 - 1); }
};

ll getNth(BitSum &bs, int index, int max_size) {
  ll l = 1, h = max_size;

  while (l < h) {
    ll m = (l + h) / 2;
    ll res = bs.calc(m);
    // printf("l = %lld, h = %lld: calc(%lld) = %lld\\n", l, h, m, res);
    if (res < index) {
      l = m + 1;
    } else {
      h = m;
    }
  }

  return (l + h) / 2;
}

void exec(int q, int lim) {
  unordered_map<int, int> number2index;
  unordered_map<int, int> index2number;
  VI incubated;
  BitSum bs = BitSum(MAX_N);
  int index;
  int count = 0;

  for (int i = 0; i < q; i++) {
    int query, x;
    scanf("%d%d", &query, &x);
    // printf("query = (%d, %d)\\n", query, x);

    switch (query) {
    case 0:
      incubated.push_back(x);
      bs.add(incubated.size(), 1);
      number2index[x] = incubated.size();
      index2number[incubated.size()] = x;
      count++;

      if (count > lim) {
        index = getNth(bs, 1, incubated.size());
        // printf("0: overflow. delete (%d, %d)\\n", index, index2number[index]);
        bs.add(index, -1);
        count--;
      }
      break;
    case 1:
      index = getNth(bs, x, incubated.size());
      // printf("1: delete by index = (%d, %d)\\n", index, index2number[index]);
      bs.add(index, -1);
      count--;
      break;
    case 2:
      index = getNth(bs, x, incubated.size());
      // printf("DEBUG 2: index = %d\\n", index);
      // printf("DEBUG 2: range = %lld\\n", bs.range(index, index));
      printf("%d\\n", index2number[index]);
      break;
    case 3:
      bs.add(number2index[x], -1);
      // printf("3: delete by number = (%d, %d)\\n", x, number2index[x]);
      count--;
      break;
    }
  }

  printf("end\\n");
}

void solve() {
  while (true) {
    int q, lim;
    scanf("%d%d", &q, &lim);

    if (q + lim == 0) {
      break;
    }

    exec(q, lim);
  }
}

int main() {
  solve();
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <iostream>
#include <queue>
#include <string>
#include <unordered_map>
#include <vector>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<int> VI;
typedef vector<ll> VL;
typedef pair<int, int> ipair;
typedef tuple<int, int, int> ituple;

// const int INF = INT_MAX;
// const ll INF = LLONG_MAX;
// const int MOD = ((int)1e9 + 7);
// const ld EPS = (1e-10);
#define PI acosl(-1)
#define MAX_N (500000)

class BitSum {
protected:
  static const int max_value = 500000 + 2;
  ll bit[max_value + 1];

public:
  BitSum(int size) {
    assert(size < max_value);
    init();
  }
  void init() {
    for (int i = 0; i < max_value; i++) {
      bit[i] = 0;
    }
  }
  void add(int idx, ll val) {
    int p = idx + 1;
    while (p < max_value) {
      bit[p] += val;
      p += p & -p;
    }
  }
  /**
   * [0, idx]のsumを求める
   */
  ll calc(int idx) {
    ll res = 0;
    int p = idx + 1;
    while (0 < p) {
      res += bit[p];
      p -= p & -p;
    }
    return res;
  }
  /**
   * [idx1, idx2]のsumを求める
   */
  ll range(int idx1, int idx2) { return calc(idx2) - calc(idx1 - 1); }
};

ll getNth(BitSum bs, int index, int max_size) {
  ll l = 1, h = max_size;
  ll prev = max_size;

  // printf("getNth; index = %d\\n", index);

  while (l < h) {
    ll m = (l + h) / 2 + (l + h) % 2;
    ll res = bs.calc(m);
    // printf("l = %lld, h = %lld: calc(%lld) = %lld\\n", l, h, m, res);
    if (res == index) {
      h = m;
    } else if (res < index) {
      l = m + 1;
    } else {
      h = m - 1;
    }

    if (abs(h - l) == prev) {
      break;
    }
    prev = abs(h - l);
  }

  return (l + h) / 2 + (l + h) % 2;
}

void exec(int q, int lim) {
  unordered_map<int, int> number2index;
  unordered_map<int, int> index2number;
  VI incubated;
  BitSum bs = BitSum(MAX_N);
  int index;
  int count = 0;

  for (int i = 0; i < q; i++) {
    int query, x;
    scanf("%d%d", &query, &x);
    // printf("query = (%d, %d)\\n", query, x);

    switch (query) {
    case 0:
      incubated.push_back(x);
      bs.add(incubated.size(), 1);
      number2index[x] = incubated.size();
      index2number[incubated.size()] = x;
      count++;

      if (count > lim) {
        index = getNth(bs, 1, incubated.size());
        // printf("0: overflow. delete (%d, %d)\\n", index, index2number[index]);
        bs.add(index, -1);
        count--;
      }
      break;
    case 1:
      index = getNth(bs, x, incubated.size());
      // printf("1: delete by index = (%d, %d)\\n", index, index2number[index]);
      bs.add(index, -1);
      count--;
      break;
    case 2:
      index = getNth(bs, x, incubated.size());
      // printf("DEBUG: index = %d\\n", index);
      printf("%d\\n", index2number[index]);
      break;
    case 3:
      bs.add(number2index[x], -1);
      // printf("1: delete by number = (%d, %d)\\n", x, number2index[x]);
      count--;
      break;
    }
  }

  printf("end\\n");
}

void solve() {
  while (true) {
    int q, lim;
    scanf("%d%d", &q, &lim);

    if (q + lim == 0) {
      break;
    }

    exec(q, lim);
  }
}

int main() {
  solve();
  return 0;
}