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

#include <bits/stdc++.h>

using namespace std;
using ll = long long;
#define int ll
using PII = pair<int, int>;
template <typename T> using V = vector<T>;
template <typename T> using VV = vector<V<T>>;
template <typename T> using VVV = vector<VV<T>>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define PB push_back

const ll INF = (1LL << 60);
const int MOD = 1000000007;

template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template <typename T> bool IN(T a, T b, T x) { return a <= x && x < b; }
template <typename T> T ceil(T a, T b) { return a / b + !!(a % b); }
template <class S, class T>
ostream &operator<<(ostream &out, const pair<S, T> &a) {
  out << '(' << a.first << ',' << a.second << ')';
  return out;
}
template <class T> ostream &operator<<(ostream &out, const vector<T> &a) {
  out << '[';
  REP(i, (int)a.size()) {
    out << a[i];
    if (i + 1 != (int)a.size())
      out << ',';
  }
  out << ']';
  return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};

int w, h;
bool used[2010][2010];

signed main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);

  while (1) {
    cin >> w >> h;
    if (!h)
      break;
    int n;
    cin >> n;
    V<int> a(n), b(n), c(n), d(n);
    REP(i, n) { cin >> a[i] >> b[i] >> c[i] >> d[i]; }

    V<int> x, y;
    REP(i, n) {
      x.PB(a[i]);
      x.PB(c[i]);
      y.PB(b[i]);
      y.PB(d[i]);
    }
    x.PB(0);
    x.PB(w);
    y.PB(0);
    y.PB(h);

    sort(ALL(x));
    sort(ALL(y));
    x.erase(unique(ALL(x)), x.end());
    y.erase(unique(ALL(y)), y.end());

    h = y.size(), w = x.size();
    VV<int> board(h, V<int>(w, 0));
    REP(i, n) {
      a[i] = lower_bound(ALL(x), a[i]) - x.begin();
      b[i] = lower_bound(ALL(y), b[i]) - y.begin();
      c[i] = lower_bound(ALL(x), c[i]) - x.begin();
      d[i] = lower_bound(ALL(y), d[i]) - y.begin();
      board[b[i]][a[i]]++;
      board[d[i]][c[i]]++;
      board[b[i]][c[i]]--;
      board[d[i]][a[i]]--;
    }

    REP(i, h) FOR(j, 1, w) board[i][j] += board[i][j - 1];
    REP(i, w) FOR(j, 1, h) board[j][i] += board[j - 1][i];

    // REP(i, h) cout << board[i] << endl;

    function<void(int, int)> dfs = [&](int x, int y) {
      used[y][x] = true;
      REP(i, 4) {
        int nx = x + dx[i], ny = y + dy[i];
        if (IN(0LL, w - 1, nx) && IN(0LL, h - 1, ny) && !used[ny][nx] &&
            !board[ny][nx]) {
          dfs(nx, ny);
        }
      }
    };

    memset(used, false, sizeof(used));
    int ret = 0;
    REP(i, h - 1) REP(j, w - 1) {
      if (!used[i][j] && !board[i][j]) {
        ret++;
        dfs(j, i);
      }
    }

    cout << ret << endl;
  }

  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;
using ll = long long;
#define int ll
using PII = pair<int, int>;
template <typename T> using V = vector<T>;
template <typename T> using VV = vector<V<T>>;
template <typename T> using VVV = vector<VV<T>>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define PB push_back

const ll INF = (1LL << 60);
const int MOD = 1000000007;

template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template <typename T> bool IN(T a, T b, T x) { return a <= x && x < b; }
template <typename T> T ceil(T a, T b) { return a / b + !!(a % b); }
template <class S, class T>
ostream &operator<<(ostream &out, const pair<S, T> &a) {
  out << '(' << a.first << ',' << a.second << ')';
  return out;
}
template <class T> ostream &operator<<(ostream &out, const vector<T> &a) {
  out << '[';
  REP(i, (int)a.size()) {
    out << a[i];
    if (i + 1 != (int)a.size())
      out << ',';
  }
  out << ']';
  return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};

const int maxh = 4010, maxw = 4010;
int csum[maxh][maxw];
void init(VV<int> vec) {
  assert(vec.size());
  REP(i, vec.size()) REP(j, vec[0].size()) {
    if (!i && !j)
      csum[i][j] = vec[i][j];
    else if (!i)
      csum[i][j] = csum[i][j - 1] + vec[i][j];
    else if (!j)
      csum[i][j] = csum[i - 1][j] + vec[i][j];
    else
      csum[i][j] =
          csum[i - 1][j] + csum[i][j - 1] - csum[i - 1][j - 1] + vec[i][j];
  }
}

int h, w, hh, ww;
int used[maxh][maxw];
void dfs(int x, int y) {
  // cout << y << " " << x << endl;
  used[y][x] = 1;
  REP(i, 4) {
    int nx = x + dx[i], ny = y + dy[i];
    if (IN(0LL, min(ww, w), nx) && IN(0LL, min(hh, h), ny) &&
        csum[ny][nx] == 0 && used[ny][nx] == 0) {
      dfs(nx, ny);
    }
  }
}

signed main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);

  while (1) {
    cin >> w >> h;
    if (!h)
      break;
    int n;
    cin >> n;
    V<int> a(n), b(n), c(n), d(n);
    REP(i, n) {
      cin >> a[i] >> b[i] >> c[i] >> d[i];
      // a[i]*=2; b[i]*=2;
      // c[i]=c[i]*2+1; d[i]=d[i]*2+1;
    }

    V<int> x, y;
    REP(i, n) {
      x.PB(max(0LL, a[i] - 1));
      x.PB(a[i]);
      x.PB(c[i]);
      x.PB(min(w, c[i] + 1));
      y.PB(max(0LL, b[i] - 1));
      y.PB(b[i]);
      y.PB(d[i]);
      y.PB(min(h, d[i] + 1));
    }
    x.PB(0);
    x.PB(w);
    y.PB(0);
    y.PB(h);

    // REP(i, w) x.PB(i);
    // REP(i, h) y.PB(i);

    sort(ALL(x));
    sort(ALL(y));
    x.erase(unique(ALL(x)), x.end());
    y.erase(unique(ALL(y)), y.end());

    hh = h, ww = w;
    h = y.size() + 1, w = x.size() + 1;
    VV<int> board(h, V<int>(w, 0));
    REP(i, n) {
      a[i] = lower_bound(ALL(x), a[i]) - x.begin();
      b[i] = lower_bound(ALL(y), b[i]) - y.begin();
      c[i] = lower_bound(ALL(x), c[i]) - x.begin();
      d[i] = lower_bound(ALL(y), d[i]) - y.begin();
      board[b[i]][a[i]]++;
      board[d[i]][c[i]]++;
      board[b[i]][c[i]]--;
      board[d[i]][a[i]]--;
    }

    // REP(i, min(hh,h)) {
    //   REP(j, min(ww,w)) {
    //     cout << board[i][j] << " ";
    //   }
    //   cout << endl;
    // }

    init(board);

    // REP(i, min(hh,h)) {
    //   REP(j, min(ww,w)) {
    //     cout << csum[i][j];
    //   }
    //   cout << endl;
    // }

    memset(used, 0, sizeof(used));
    int ret = 0;
    REP(i, min(hh, h)) REP(j, min(ww, w)) {
      if (!used[i][j] && !csum[i][j]) {
        // cout << i << "," << j << endl;
        dfs(j, i);
        ret++;
      }
    }
    cout << ret << endl;
  }

  return 0;
}