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

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

const function<int(int, int)> minQ = [](int l, int r) { return min(l, r); };
const function<int(int, int)> maxQ = [](int l, int r) { return max(l, r); };

int data[1 << 23];
int v[1 << 20];

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;
  }

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) {
    pi += h;
    pj += w;
    data[pi * w * 2 + pj] = val;
    int tj = pj;
    while (tj >>= 1) {
      data[pi * w * 2 + tj] =
          merge(data[pi * w * 2 + tj * 2], data[pi * w * 2 + tj * 2 + 1]);
    }
    while (pi >>= 1) {
      data[pi * w * 2 + pj] =
          merge(data[(pi * 2) * w * 2 + pj], data[(pi * 2 + 1) * w * 2 + pj]);
      tj = pj;
      while (tj >>= 1) {
        data[pi * w * 2 + tj] =
            merge(data[pi * w * 2 + tj * 2], data[pi * w * 2 + tj * 2 + 1]);
      }
    }
  }
  T Find(int li, int lj, int ri, int rj) {
    li += h, ri += h + 1;
    T res1 = id, res2 = id;
    while (li < ri) {
      if (li & 1) {
        int l = lj + w, r = rj + w + 1;
        T t1 = id, t2 = id;
        while (l < r) {
          if (l & 1)
            t1 = merge(t1, data[li * w * 2 + l++]);
          if (r & 1)
            t2 = merge(data[li * w * 2 + --r], t2);
          l >>= 1, r >>= 1;
        }
        res1 = merge(res1, merge(t1, t2));
        li++;
      }
      if (ri & 1) {
        ri--;
        int l = lj + w, r = rj + w + 1;
        T t1 = id, t2 = id;
        while (l < r) {
          if (l & 1)
            t1 = merge(t1, data[ri * w * 2 + l++]);
          if (r & 1)
            t2 = merge(data[ri * w * 2 + --r], t2);
          l >>= 1, r >>= 1;
        }
        res2 = merge(merge(t1, t2), res2);
      }
      li >>= 1, ri >>= 1;
    }
    return merge(res1, res2);
  }
};

int main() {
  cin.sync_with_stdio(false);
  cin.tie(0);
  int r, c, q, r1, r2, c1, c2;
  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> st(r, c, INT_MAX, minQ);
    while (q--) {
      cin >> r1 >> c1 >> r2 >> c2;
      printf("%d\\n", st.Find(r1, c1, r2, c2));
    }
  }
  return 0;
}

Error: MLE

Fixed submission:

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

const function<int(int, int)> minQ = [](int l, int r) { return min(l, r); };

template <typename T> class SegmentTree {
  using func_t = function<T(T, T)>;
  const int n;
  const T id;
  func_t merge;
  vector<T> data;
  int size(int n) {
    int res;
    for (res = 1; res < n; res <<= 1)
      ;
    return res;
  }

public:
  SegmentTree(int n_, T id_, func_t merge_)
      : n(size(n_)), id(id_), merge(merge_), data(n * 2, id) {}
  void Init(const vector<T> &data_) {
    for (int i = 0; i < (int)data_.size(); i++)
      data[i + n] = data_[i];
    for (int i = n - 1; i >= 0; i--)
      data[i] = merge(data[i * 2], data[i * 2 + 1]);
  }
  void Update(int p, T val) {
    p += n;
    data[p] = val;
    while (p >>= 1)
      data[p] = merge(data[p * 2], data[p * 2 + 1]);
  }
  void Add(int p, T val) {
    p += n;
    data[p] += val;
    while (p >>= 1)
      data[p] = merge(data[p * 2], data[p * 2 + 1]);
  }
  T Find(int i) { return data[i + n]; }
  T Find(int l, int r) {
    l += n;
    r += n + 1;
    T res1 = id, res2 = id;
    while (l < r) {
      if (l & 1)
        res1 = merge(res1, data[l++]);
      if (r & 1)
        res2 = merge(data[--r], res2);
      l >>= 1;
      r >>= 1;
    }
    return merge(res1, res2);
  }
};

template <typename T> class SegmentTree2 {
  using func_t = function<T(T, T)>;
  const int h;
  const T id;
  func_t merge;
  vector<SegmentTree<T>> data;
  int size(int n) {
    int res;
    for (res = 1; res < n; res <<= 1)
      ;
    return res;
  }

public:
  SegmentTree2(int h_, int w_, T id_, func_t merge_)
      : h(size(h_)), id(id_), merge(merge_),
        data(h * 2, SegmentTree<T>(w_, id, merge)) {}
  void Init(const vector<vector<T>> &v) {
    for (int i = 0; i < (int)v.size(); i++)
      data[i + h].Init(v[i]);
    int w = v.front().size();
    vector<T> tmp(w);
    for (int i = h - 1; i > 0; i--) {
      for (int j = 0; j < w; j++) {
        tmp[j] = merge(data[i * 2].Find(j), data[i * 2 + 1].Find(j));
      }
      data[i].Init(tmp);
    }
  }
  void Update(int i, int j, T val) {
    i += h;
    data[i].Update(j, val);
    while (i >>= 1)
      data[i].Update(j, merge(data[i * 2].Find(j), data[i * 2 + 1].Find(j)));
  }
  void Add(int i, int j, T val) {
    i += h;
    data[i].Add(j, val);
    while (i >>= 1)
      data[i].Update(j, merge(data[i * 2].Find(j), data[i * 2 + 1].Find(j)));
  }
  T Find(int i, int j) { return data[i + h].Find(j); }
  T Find(int li, int lj, int ri, int rj) {
    li += h;
    ri += h + 1;
    T res1 = id, res2 = id;
    while (li < ri) {
      if (li & 1)
        res1 = merge(res1, data[li++].Find(lj, rj));
      if (ri & 1)
        res2 = merge(data[--ri].Find(lj, rj), res2);
      li >>= 1;
      ri >>= 1;
    }
    return merge(res1, res2);
  }
};

int main() {
  cin.sync_with_stdio(false);
  cin.tie(0);
  int r, c, q, r1, r2, c1, c2;
  vector<vector<int>> v;
  v.reserve(1e6);
  while (cin >> r >> c >> q, r | c | q) {
    v.assign(r, vector<int>(c));
    for (int i = 0; i < r; i++) {
      for (int j = 0; j < c; j++) {
        cin >> v[i][j];
      }
    }
    SegmentTree2<int> st(r, c, INT_MAX, minQ);
    st.Init(v);
    while (q--) {
      cin >> r1 >> c1 >> r2 >> c2;
      printf("%d\\n", st.Find(r1, c1, r2, c2));
    }
  }
  return 0;
}