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

#include <iostream>
#include <tuple>
#include <unordered_map>
#include <vector>

#define loop(n, i) for (int i = 0; i < n; i++)
#define repeat(n) for (int __i = 0; __i < n; __i++)
#define loop_from_to(from, to, i) for (int i = from; i <= to; i++)
#define multi_cin(n, array)                                                    \\
  loop(n, i) { cin >> array[i]; }
#define assign_if_smaller(var, val)                                            \\
  if (var > val)                                                               \\
    var = val;
#define assign_if_larger(var, val)                                             \\
  if (var < val)                                                               \\
    var = val;

using namespace std;
int x_size, y_size;
int x_min, x_max;
int y_min, y_max;
int type;
unordered_map<int, vector<tuple<int, int, int>>> sheets;

void init() {
  x_min = 0;
  y_min = 0;
  x_max = 0;
  y_max = 0;
  x_size = 0;
  y_size = 0;
}

void add_sheet(int x1, int y1, int x2, int y2) {
  assign_if_smaller(x_min, x1);
  assign_if_smaller(y_min, y1);
  assign_if_larger(x_max, x2);
  assign_if_larger(y_max, y2);
  x_size = x_max + 1;
  y_size = y_max + 1;

  auto t = make_tuple(y1, x2, y2);
  if (sheets.count(x1) == 0) {
    sheets[x1] = {t};
  } else {
    sheets[x1].push_back(t);
  }
}
vector<tuple<int, int, int>> &find_end_points(int x, int y) {
  return sheets[x];
}

void calc_and_output() {
  long area = 0;
  long lines = 0;

  int right_area_end_point[y_size];
  loop(y_size, i) right_area_end_point[i] = -1;

  bool *is_area[2];
  is_area[0] = new bool[y_size];
  is_area[1] = new bool[y_size];
  loop(y_size, i) {
    is_area[0][i] = false;
    is_area[1][i] = false;
  }

  loop(x_size, x_i) {
    // update right_area_end_point
    auto &points = find_end_points(x_i, 0);

    // per point operation
    for (auto &&point : points) {
      int y_i = get<0>(point), x = get<1>(point), y = get<2>(point);

      loop_from_to(y_i, y - 1, p_i) {
        assign_if_larger(right_area_end_point[p_i], x);
      }
    }

    loop(y_size, y_i) {

      // included in some sheets
      if (right_area_end_point[y_i] > x_i) {
        area += 1;
        is_area[x_i % 2][y_i] = true;
      } else {
        is_area[x_i % 2][y_i] = false;
      }

      // line check
      if (type == 2) {
        // left line exists
        if (is_area[(x_i % 2) ^ 1][y_i] != is_area[x_i % 2][y_i])
          lines += 1;

        // bottom line exists
        if ((y_i == 0 && is_area[x_i % 2][y_i]) ||
            (y_i > 0 && (is_area[x_i % 2][y_i - 1] != is_area[x_i % 2][y_i])))
          lines += 1;
      }
    }
  }

  cout << area << endl;
  if (type == 2)
    cout << lines << endl;

  delete is_area[0];
  delete is_area[1];
}

int main(int argc, char const *argv[]) {
  while (true) {
    int n;
    cin >> n >> type;
    if (n == 0 && type == 0)
      break;

    init();

    repeat(n) {
      int p[4];
      multi_cin(4, p);
      add_sheet(p[0], p[1], p[2], p[3]);
    }

    calc_and_output();
    sheets.clear();
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <iostream>
#include <unordered_map>
#include <vector>

#define loop(n, i) for (int i = 0; i < n; i++)
#define repeat(n) for (int __i = 0; __i < n; __i++)
#define loop_from_to(from, to, i) for (int i = from; i <= to; i++)
#define multi_cin(n, array)                                                    \\
  loop(n, i) { cin >> array[i]; }
#define assign_if_smaller(var, val)                                            \\
  if (var > val)                                                               \\
    var = val;
#define assign_if_larger(var, val)                                             \\
  if (var < val)                                                               \\
    var = val;

namespace std {
template <> struct hash<pair<int, int>> {
  size_t operator()(pair<int, int> const &key) const {
    int x = key.first, y = key.second;
    return (x + y) * (x + y + 1) / 2 + y;
  }
};
} // namespace std

using namespace std;
int x_size, y_size;
int x_min, x_max;
int y_min, y_max;
int type;
unordered_map<pair<int, int>, vector<pair<int, int>>> sheets;

void init() {
  x_min = 0;
  y_min = 0;
  x_max = 0;
  y_max = 0;
  x_size = 0;
  y_size = 0;
}

void add_sheet(int x1, int y1, int x2, int y2) {
  assign_if_smaller(x_min, x1);
  assign_if_smaller(y_min, y1);
  assign_if_larger(x_max, x2);
  assign_if_larger(y_max, y2);
  x_size = x_max + 1;
  y_size = y_max + 1;

  pair<int, int> p = {x1, y1};

  int c = sheets.count({x1, y1});
  if (sheets.count({x1, y1}) == 0) {
    sheets[p] = {{x2, y2}};
  } else {
    sheets[p].push_back({x2, y2});
  }
}

vector<pair<int, int>> &find_end_points(int x, int y) {
  pair<int, int> p = {x, y};
  return sheets[p];
}

void calc_and_output() {
  long area = 0;
  long lines = 0;

  int right_area_end_point[y_size];
  loop(y_size, i) right_area_end_point[i] = -1;

  bool *is_area[2];
  is_area[0] = new bool[y_size];
  is_area[1] = new bool[y_size];
  loop(y_size, i) {
    is_area[0][i] = false;
    is_area[1][i] = false;
  }

  loop(x_size, x_i) {
    loop(y_size, y_i) {
      // update right_area_end_point
      auto &&points = find_end_points(x_i, y_i);

      // per point operation
      for (auto &&point : points) {
        int x = point.first, y = point.second;

        loop_from_to(y_i, y - 1, p_i) {
          assign_if_larger(right_area_end_point[p_i], x);
        }
      }
    }

    loop(y_size, y_i) {

      // included in some sheets
      if (right_area_end_point[y_i] > x_i) {
        area += 1;
        is_area[x_i % 2][y_i] = true;
      } else {
        is_area[x_i % 2][y_i] = false;
      }

      // line check
      if (type == 2) {
        // left line exists
        if (is_area[(x_i % 2) ^ 1][y_i] != is_area[x_i % 2][y_i])
          lines += 1;

        // bottom line exists
        if ((y_i == 0 && is_area[x_i % 2][y_i]) ||
            (y_i > 0 && (is_area[x_i % 2][y_i - 1] != is_area[x_i % 2][y_i])))
          lines += 1;
      }
    }
  }

  cout << area << endl;
  if (type == 2)
    cout << lines << endl;

  delete is_area[0];
  delete is_area[1];
}

int main(int argc, char const *argv[]) {
  while (true) {
    int n;
    cin >> n >> type;
    if (n == 0 && type == 0)
      break;

    init();

    repeat(n) {
      int p[4];
      multi_cin(4, p);
      add_sheet(p[0], p[1], p[2], p[3]);
    }

    calc_and_output();
    sheets.clear();
  }
  return 0;
}