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

#include <bits/stdc++.h>
using namespace std;

int data[1 << 23];
int v[1 << 20];
int r, c, q, r1, r2, c1, c2;

template <typename T> class SegmentTree2 {
  using func_t = function<T(T, T)>;
  const int h, w;
  const T id;
  func_t merge;
  int size(int n) {
    int res;
    for (res = 1; res < n; res <<= 1)
      ;
    return res;
  }
  T sub_h(int li, int lj, int ri, int rj, int si, int ti, int k) {
    if (ri <= si || ti <= li)
      return id;
    if (li <= si && ti <= ri)
      return sub_w(lj, rj, 0, w, k, 1);
    const int mi = (si + ti) / 2;
    return merge(sub_h(li, lj, ri, rj, si, mi, k * 2),
                 sub_h(li, lj, ri, rj, mi, ti, k * 2 + 1));
  }
  T sub_w(int lj, int rj, int sj, int tj, int i, int k) {
    if (rj <= sj || tj <= lj)
      return id;
    if (lj <= sj && tj <= rj)
      return data[i * w * 2 + k];
    const int mj = (sj + tj) / 2;
    return merge(sub_w(lj, rj, sj, mj, i, k * 2),
                 sub_w(lj, rj, mj, tj, i, k * 2 + 1));
  }

public:
  SegmentTree2(int h_, int w_, T id_, func_t merge_)
      : h(size(h_)), w(size(w_)), id(id_), merge(merge_) {
    fill(data, data + (1 << 23), id);
    for (int i = 0; i < h_; i++)
      for (int j = 0; j < w_; j++)
        data[(h + i) * w * 2 + w + j] = v[i * w_ + j];
    for (int i = h * 2 - 1; i >= h; i--)
      for (int j = w - 1; j > 0; j--)
        data[i * w * 2 + j] =
            merge(data[i * w * 2 + j * 2], data[i * w * 2 + j * 2 + 1]);
    for (int i = h - 1; i > 0; i--)
      for (int j = 1; j < w * 2; j++)
        data[i * w * 2 + j] =
            merge(data[i * 2 * w * 2 + j], data[(i * 2 + 1) * w * 2 + j]);
  }
  // void Update(int pi, int pj, T val) { }
  // void Add(int pi, int pj, T val) { }
  T Find(int li, int lj, int ri, int rj) {
    return sub_h(li, lj, ri + 1, rj + 1, 0, h, 1);
  }
};

int main() {
  while (cin >> r >> c >> q, r | c | q) {
    for (int i = 0; i < r; i++) {
      for (int j = 0; j < c; j++) {
        cin >> v[i * c + j];
      }
    }
    SegmentTree2<int> st2(r, c, INT_MAX,
                          [](int l, int r) { return min(l, r); });
    while (q--) {
      cin >> r1 >> c1 >> r2 >> c2;
      cout << st2.Find(r1, c1, r2, c2) << endl;
    }
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

int data[1 << 23];

template <typename T> class SegmentTree2 {
  using func_t = function<T(T, T)>;
  const int h, w;
  const T id;
  func_t merge;
  int size(int n) {
    int res;
    for (res = 1; res < n; res <<= 1)
      ;
    return res;
  }
  T sub_h(int li, int lj, int ri, int rj, int si, int ti, int k) {
    if (ri <= si || ti <= li)
      return id;
    if (li <= si && ti <= ri)
      return sub_w(lj, rj, 0, w, k, 1);
    const int mi = (si + ti) / 2;
    return merge(sub_h(li, lj, ri, rj, si, mi, k * 2),
                 sub_h(li, lj, ri, rj, mi, ti, k * 2 + 1));
  }
  T sub_w(int lj, int rj, int sj, int tj, int i, int k) {
    if (rj <= sj || tj <= lj)
      return id;
    if (lj <= sj && tj <= rj)
      return data[i * w * 2 + k];
    const int mj = (sj + tj) / 2;
    return merge(sub_w(lj, rj, sj, mj, i, k * 2),
                 sub_w(lj, rj, mj, tj, i, k * 2 + 1));
  }

public:
  SegmentTree2(vector<vector<T>> data_, T id_, func_t merge_)
      : h(size(data_.size())), w(size(data_.front().size())), id(id_),
        merge(merge_) {
    fill(data, data + (1 << 23), id);
    for (int i = 0; i < (int)data_.size(); i++)
      for (int j = 0; j < (int)data_.front().size(); j++)
        data[(h + i) * w * 2 + w + j] = data_[i][j];
    for (int i = h * 2 - 1; i >= h; i--)
      for (int j = w - 1; j > 0; j--)
        data[i * w * 2 + j] =
            merge(data[i * w * 2 + j * 2], data[i * w * 2 + j * 2 + 1]);
    for (int i = h - 1; i > 0; i--)
      for (int j = 1; j < w * 2; j++)
        data[i * w * 2 + j] =
            merge(data[i * 2 * w * 2 + j], data[(i * 2 + 1) * w * 2 + j]);
  }
  // void Update(int pi, int pj, T val) { }
  // void Add(int pi, int pj, T val) { }
  T Find(int li, int lj, int ri, int rj) {
    return sub_h(li, lj, ri + 1, rj + 1, 0, h, 1);
  }
};

int main() {
  int r, c, q, r1, r2, c1, c2;
  while (cin >> r >> c >> q, r | c | q) {
    vector<vector<int>> v(r, vector<int>(c));
    for (int i = 0; i < r; i++) {
      for (int j = 0; j < c; j++) {
        cin >> v[i][j];
      }
    }
    SegmentTree2<int> st2(v, INT_MAX, [](int l, int r) { return min(l, r); });
    while (q--) {
      cin >> r1 >> c1 >> r2 >> c2;
      cout << st2.Find(r1, c1, r2, c2) << endl;
    }
  }
  return 0;
}