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

#include <algorithm>
#include <climits>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#define REP(i, n) for (int i = 0; i < (int)(n); i++)

#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

template <class T> T getAs() {
  T v;
  std::cin >> v;
  return v;
}
inline int getInt() { return getAs<int>(); }

using namespace std;

int main() {
  while (true) {
    int m = getInt();
    int c = getInt();
    int n = getInt();

    if (m + c + n == 0)
      break;

    vector<vector<int>> b(n);

    REP(i, n) {
      int k = getInt();
      b[i] = vector<int>(k);
      REP(j, k) b[i][j] = getInt();
    }

    vector<set<int>> D(m);
    vector<int> idx(n);
    int ans = 0;
    int end = 0;
    int id = 0;
    map<int, int> lru;

    while (end != n) {
      REP(i, n) if (idx[i] != b[i].size()) {
        int book = b[i][idx[i]++];

        if (idx[i] == b[i].size())
          end++;

        // search book
        bool ok = false;
        REP(j, m) if (D[j].count(book)) {
          ans += j + 1;
          D[j].erase(book);
          ok = true;
          break;
        }

        if (!ok)
          ans += m + 1;

        // return book
        if (D[0].size() == c) {
          // put on first D
          int tmp = -1;
          REP(j, m) if (D[j].size() != c) {
            tmp = j;
            D[j].insert(book);
            tmp = j;
            ans += j + 1;
            break;
          }
          if (tmp == -1) {
            ans += m + 1;
          }

          // select lru book
          int lruidx = -1;
          int lruid = INT_MAX;

          FOR(it, D[0]) {
            if (lruid > lru[*it]) {
              lruidx = *it;
              lruid = lru[*it];
            }
          }

          ans += 1;
          D[0].erase(lruidx);

          // put on first D
          ok = false;
          for (int j = 1; j < m; j++)
            if (D[j].size() != c) {
              D[j].insert(lruidx);
              ans += j + 1;
              ok = true;
              break;
            }
          if (!ok)
            ans += m + 1;

          // take book
          if (tmp == -1)
            ans += m + 1;
          else {
            ans += tmp + 1;
            D[tmp].erase(book);
          }

          // put book on D1
          ans += 1;
          D[0].insert(book);
        } else {
          D[0].insert(book);
          ans += 1;
        }

        lru[book] = id++;
      }
    }

    printf("%d\\n", ans);
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <cassert>
#include <cstdio>
#include <iostream>
#include <list>
#include <set>
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

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

using namespace std;

struct Sectors {
  int start;
  int end;
  int id;
  Sectors() : start(0), end(1000000010), id(-1) {}
  Sectors(int s, int e, int i) : start(s), end(e), id(i) {}

  int size() { return end - start + 1; }
  bool isEmpty() { return id == -1; }
  bool isIn(int sec) { return start <= sec && sec <= end; }
};

int main() {
  int n;
  while (scanf("%d", &n), n) {
    list<Sectors> ss;
    int emp = 0;

    ss.push_back(Sectors());

    REP(cc, n) {
      char buff[2];
      scanf("%s", buff);
      if (buff[0] == 'W') {
        int l, s;
        scanf("%d%d", &l, &s);

        if (emp == 0) {
          list<Sectors>::iterator it = ss.end();
          --it;
          int start = it->start;
          int end = start + s;
          it->start = end + 1;
          it = ss.insert(it, Sectors(start, end, l));
        } else {
          list<Sectors>::iterator it = ss.begin();
          while (s > 0) {
            if (it->isEmpty()) {
              int sz = it->size();
              if (sz > s) {
                int start = it->start;
                int end = start + s;
                it->start = end + 1;
                it = ss.insert(it, Sectors(start, end, l));
                break;
              } else {
                s -= sz;
                it->id = l;
                emp--;
              }
            }

            assert(it != ss.end());
            ++it;
          }
        }
      } else if (buff[0] == 'D') {
        int l;
        scanf("%d", &l);
        FOR(it, ss) {
          if (it->id == l) {
            it->id = -1;
            emp++;
          }
        }
      } else {
        int sec;
        scanf("%d", &sec);

        FOR(it, ss) {
          if (it->isIn(sec)) {
            printf("%d\\n", it->id);
            break;
          }
        }
      }

      // FOR(it, ss)printf("[%d,%d]:%d ", it->start, it->end, it->id);puts("");
    }
    puts("");
  }
  return 0;
}