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

#include <bits/stdc++.h>

#define FOR(i, a, b) for (int i = (a); i < ((int)b); ++i)
#define RFOR(i, a) for (int i = (a); i >= 0; --i)
#define FOE(i, a) for (auto i : a)
#define ALL(c) (c).begin(), (c).end()
#define RALL(c) (c).rbegin(), (c).rend()
#define DUMP(x) cerr << #x << " = " << (x) << endl;
#define SUM(x) std::accumulate(ALL(x), 0LL)
#define MIN(v) *std::min_element(v.begin(), v.end())
#define MAX(v) *std::max_element(v.begin(), v.end())
#define EXIST(v, x) (std::find(v.begin(), v.end(), x) != v.end())
#define BIT(n) (1LL << (n))
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());

typedef long long LL;
template <typename T> using V = std::vector<T>;
template <typename T> using VV = std::vector<std::vector<T>>;
template <typename T> using VVV = std::vector<std::vector<std::vector<T>>>;

template <class T> inline T ceil(T a, T b) { return (a + b - 1) / b; }
template <class T> inline void print(T x) { std::cout << x << std::endl; }
template <class T> inline void print_vec(const std::vector<T> &v) {
  for (int i = 0; i < v.size(); ++i) {
    if (i != 0) {
      std::cout << " ";
    }
    std::cout << v[i];
  }
  std::cout << "\\n";
}
template <class T> inline bool inside(T y, T x, T H, T W) {
  return 0 <= y and y < H and 0 <= x and x < W;
}
template <class T> inline double euclidean_distance(T y1, T x1, T y2, T x2) {
  return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
template <class T> inline double manhattan_distance(T y1, T x1, T y2, T x2) {
  return abs(x1 - x2) + abs(y1 - y2);
}

const int INF = 1L << 30;
const double EPS = 1e-9;
const std::string YES = "YES", Yes = "Yes", NO = "NO", No = "No";
const std::vector<int> dy4 = {0, 1, 0, -1},
                       dx4 = {1, 0, -1, 0}; // 4近傍（右, 下, 左, 上）
const std::vector<int> dy8 = {0, -1, 0, 1, 1, -1, -1, 1},
                       dx8 = {1, 0, -1, 0, 1, 1, -1, -1};

class Imos {
public:
  std::vector<int> line;
  std::vector<std::vector<int>> field;
  int mode = 0;

  // 1次元imos
  Imos(int N) {
    this->mode = 1;
    this->line.resize(N + 1, 0);
  }

  // 2次元imos
  Imos(int H, int W) {
    this->mode = 2;
    this->field.resize(H + 1, std::vector<int>(W + 1, 0));
  }

  // [left, right)に+1
  void add(int left, int right) {
    assert(left < right);
    line[left]++;
    line[right]--;
  }

  // 左上(y1, x1)から右下(y2, x2)に+1する
  // 半開区間なので(y2, x2)は含まない
  void add(int y1, int x1, int y2, int x2) {
    assert(y1 < y2);
    assert(x1 < x2);

    field.at(y1).at(x1)++; // 左上
    field.at(y1).at(x2)--; // 右上
    field.at(y2).at(x1)--; // 左下
    field.at(y2).at(x2)++; // 右下
  }

  void build() {
    if (mode == 1) {
      build1();
    }
    if (mode == 2) {
      build2();
    }
  }

  void debug() {
    if (mode == 1) {
      debug1();
    }
    if (mode == 2) {
      debug2();
    }
  }

private:
  void build1() {
    for (int i = 1; i < line.size(); ++i) {
      line[i] += line[i - 1];
    }
  }

  void build2() {
    // 横方向への累積和
    for (int y = 0; y < field.size(); ++y) {
      for (int x = 1; x < field.at(0).size(); ++x) {
        field.at(y).at(x) += field.at(y).at(x - 1);
      }
    }
    // 縦方向の累積和
    for (int y = 1; y < field.size(); ++y) {
      for (int x = 0; x < field.at(0).size(); ++x) {
        field.at(y).at(x) += field.at(y - 1).at(x);
      }
    }
  }

  void debug1() {
    for (int i = 0; i < line.size(); ++i) {
      std::cout << line.at(i) << " ";
    }
    std::cout << std::endl;
  }

  void debug2() {
    for (int y = 0; y < field.size(); ++y) {
      for (int x = 0; x < field.size(); ++x) {
        std::cout << field.at(y).at(x) << " ";
      }
      std::cout << std::endl;
    }
  }
};

using namespace std;

bool solve(int H, int W, vector<tuple<int, int, int>> v) {
  Imos imos_y(H + 1);
  Imos imos_x(W + 1);

  FOR(i, 0, v.size()) {
    int x, y, w;
    tie(x, y, w) = v[i];

    int y1 = max(0, y - w);
    int y2 = min(H, y + w);
    int x1 = max(0, x - w);
    int x2 = min(W, x + w);

    imos_y.add(y1, y2);
    imos_x.add(x1, x2);
  }
  imos_y.build();
  imos_x.build();

  bool ok1 = true, ok2 = true;
  FOR(y, 0, H) {
    if (imos_y.line[y] == 0) {
      ok1 = false;
    }
  }
  FOR(x, 0, W) {
    if (imos_x.line[x] == 0) {
      ok2 = false;
    }
  }
  return ok1 or ok2;
}

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

  int N, W, H;
  cin >> N >> W >> H;

  vector<tuple<int, int, int>> v;
  FOR(i, 0, N) {
    int x, y, w;
    cin >> x >> y >> w;
    v.emplace_back(make_tuple(x, y, w));
  }

  if (solve(H, W, v)) {
    print("Yes");
  } else {
    print("No");
  }

  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>

#define FOR(i, a, b) for (int i = (a); i < ((int)b); ++i)
#define RFOR(i, a) for (int i = (a); i >= 0; --i)
#define FOE(i, a) for (auto i : a)
#define ALL(c) (c).begin(), (c).end()
#define RALL(c) (c).rbegin(), (c).rend()
#define DUMP(x) cerr << #x << " = " << (x) << endl;
#define SUM(x) std::accumulate(ALL(x), 0LL)
#define MIN(v) *std::min_element(v.begin(), v.end())
#define MAX(v) *std::max_element(v.begin(), v.end())
#define EXIST(v, x) (std::find(v.begin(), v.end(), x) != v.end())
#define BIT(n) (1LL << (n))
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());

typedef long long LL;
template <typename T> using V = std::vector<T>;
template <typename T> using VV = std::vector<std::vector<T>>;
template <typename T> using VVV = std::vector<std::vector<std::vector<T>>>;

template <class T> inline T ceil(T a, T b) { return (a + b - 1) / b; }
template <class T> inline void print(T x) { std::cout << x << std::endl; }
template <class T> inline void print_vec(const std::vector<T> &v) {
  for (int i = 0; i < v.size(); ++i) {
    if (i != 0) {
      std::cout << " ";
    }
    std::cout << v[i];
  }
  std::cout << "\\n";
}
template <class T> inline bool inside(T y, T x, T H, T W) {
  return 0 <= y and y < H and 0 <= x and x < W;
}
template <class T> inline double euclidean_distance(T y1, T x1, T y2, T x2) {
  return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
template <class T> inline double manhattan_distance(T y1, T x1, T y2, T x2) {
  return abs(x1 - x2) + abs(y1 - y2);
}

const int INF = 1L << 30;
const double EPS = 1e-9;
const std::string YES = "YES", Yes = "Yes", NO = "NO", No = "No";
const std::vector<int> dy4 = {0, 1, 0, -1},
                       dx4 = {1, 0, -1, 0}; // 4近傍（右, 下, 左, 上）
const std::vector<int> dy8 = {0, -1, 0, 1, 1, -1, -1, 1},
                       dx8 = {1, 0, -1, 0, 1, 1, -1, -1};

class Imos {
public:
  std::vector<std::vector<long long>> tiles;

  // 2次元imos
  Imos(int H, int W) {
    this->tiles.resize(H + 1, std::vector<long long>(W + 1, 0));
  }

  // 左上(y1, x1)から右下(y2, x2)
  // 半開区間なので(y2, x2)は含まない
  void add(int y1, int x1, int y2, int x2) {
    assert(y1 < y2);
    assert(x1 < x2);

    tiles.at(y1).at(x1)++; // 左上
    tiles.at(y1).at(x2)--; // 右上
    tiles.at(y2).at(x1)--; // 左下
    tiles.at(y2).at(x2)++; // 右下
  }

  void build() {
    // 横方向への累積和
    for (int y = 0; y < tiles.size(); y++) {
      for (int x = 1; x < tiles.at(0).size(); x++) {
        tiles.at(y).at(x) += tiles.at(y).at(x - 1);
      }
    }
    // 縦方向の累積和
    for (int y = 1; y < tiles.size(); y++) {
      for (int x = 0; x < tiles.at(0).size(); x++) {
        tiles.at(y).at(x) += tiles.at(y - 1).at(x);
      }
    }
  }

  void debug() {
    for (int y = 0; y < tiles.size(); ++y) {
      for (int x = 0; x < tiles.size(); ++x) {
        std::cout << tiles.at(y).at(x) << " ";
      }
      std::cout << std::endl;
    }
  }
};

using namespace std;
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N, W, H;
  cin >> N >> W >> H;

  Imos imos(H + 1, W + 1);

  FOR(i, 0, N) {
    int x, y, w;
    cin >> x >> y >> w;
    int y1 = max(0, y - w);
    int x1 = max(0, x - w);
    int y2 = min(H, y + w);
    int x2 = min(W, x + w);

    imos.add(y1, 0, y2 + 1, W + 1);
    imos.add(0, x1, H + 1, x2 + 1);
  }
  imos.build();

  FOR(y, 0, H + 1) {
    FOR(x, 0, W + 1) {
      if (imos.tiles[y][x] == 0) {
        print("No");
        return 0;
      }
    }
  }
  print("Yes");

  return 0;
}