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


#include <algorithm>
#include <iostream>
#include <tuple>
#include <vector>
using namespace std;

const int MAX = 10000;

struct Sheet {
  int left, bottom, right, top;
};
bool operator<(const Sheet &lhs, const Sheet &rhs) {
  if (lhs.bottom != rhs.bottom)
    return lhs.bottom < rhs.bottom;
  return lhs.top < rhs.top;
}

struct Range {
  int bottom, top;
  Range(const int bottom, const int top) : bottom(bottom), top(top) {}
};

int main() {
  int n, r;
  while (cin >> n >> r, n | r) {
    vector<vector<Range>> list(MAX + 1);
    vector<Sheet> sheet(n);
    for (auto &s : sheet)
      cin >> s.left >> s.bottom >> s.right >> s.top;

    sort(sheet.begin(), sheet.end());
    for (auto s : sheet)
      for (int x = s.left; x < s.right; ++x) {
        for (int i = 0; i < list[x].size(); ++i) {
          if (list[x][i].top < s.bottom)
            continue;
          list[x][i].top = max(list[x][i].top, s.top);
          while (i + 1 < list[x].size() &&
                 list[x][i].top >= list[x][i + 1].bottom) {
            list[x][i].top = max(list[x][i].top, list[x][i + 1].top);
            list[x].erase(list[x].begin() + i + 1);
          }
          break;
        }
        if (list[x].empty() || list[x].back().top < s.bottom)
          list[x].emplace_back(s.bottom, s.top);
      }

    int area = 0, circumference = 0;
    int length, touch_left = 0, touch_right;
    for (int x = 0; x < list.size(); ++x) {
      if (list[x].empty())
        continue;
      length = touch_right = 0;
      for (const auto &l : list[x]) {
        length += l.top - l.bottom;
        for (const auto &l2 : list[x + 1]) {
          if (l.top < l2.bottom || l2.top < l.bottom)
            continue;
          touch_right += min(l.top, l2.top) - max(l.bottom, l2.bottom);
        }
      }
      area += length;
      circumference += list[x].size() * 2;
      circumference += 2 * length - touch_left - touch_right;
      touch_left = touch_right;
    }

    cout << area << endl;
    if (r == 2)
      cout << circumference << endl;
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

struct Square {
  int left, top, right, bottom;
};

int main() {
  int n, r;
  while (cin >> n >> r, n | r) {
    vector<int> x = {0}, y = {0};
    vector<Square> sheet(n);
    for (auto &s : sheet) {
      cin >> s.left >> s.top >> s.right >> s.bottom;
      y.push_back(++s.top);
      y.push_back(++s.bottom);
      x.push_back(++s.left);
      x.push_back(++s.right);
    }
    sort(y.begin(), y.end());
    sort(x.begin(), x.end());
    y.erase(unique(y.begin(), y.end()), y.end());
    x.erase(unique(x.begin(), x.end()), x.end());

    vector<vector<int>> dp(y.size(), vector<int>(x.size(), 0));
    for (const auto &s : sheet) {
      int top = lower_bound(y.begin(), y.end(), s.top) - y.begin();
      int bottom = lower_bound(y.begin(), y.end(), s.bottom) - y.begin();
      int left = lower_bound(x.begin(), x.end(), s.left) - x.begin();
      int right = lower_bound(x.begin(), x.end(), s.right) - x.begin();
      ++dp[top][left];
      --dp[top][right];
      --dp[bottom][left];
      ++dp[bottom][right];
    }

    for (int i = 0; i < y.size(); ++i)
      for (int j = 1; j < x.size(); ++j)
        dp[i][j] += dp[i][j - 1];
    for (int j = 0; j < x.size(); ++j)
      for (int i = 1; i < y.size(); ++i)
        dp[i][j] += dp[i - 1][j];

    int area = 0, circumference = 0;
    for (int i = 1; i < y.size() - 1; ++i)
      for (int j = 1; j < x.size() - 1; ++j) {
        if (!dp[i][j])
          continue;
        area += (y[i + 1] - y[i]) * (x[j + 1] - x[j]);
        if (!dp[i - 1][j])
          circumference += (x[j + 1] - x[j]);
        if (!dp[i + 1][j])
          circumference += (x[j + 1] - x[j]);
        if (!dp[i][j - 1])
          circumference += (y[i + 1] - y[i]);
        if (!dp[i][j + 1])
          circumference += (y[i + 1] - y[i]);
      }
    cout << area << endl;
    if (r == 2)
      cout << circumference << endl;
  }
}