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;
  }
  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) {
    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) {
    return sub_h(li, lj, ri + 1, rj + 1, 0, h, 1);
  }
};

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); };
const function<int(int, int)> maxQ = [](int l, int r) { return max(l, r); };

int merge(int l, int r) { return min(l, r); }

template <typename T> class SegmentTree {
  const int n;
  const T id;
  vector<T> data;
  int size(int n) {
    int res;
    for (res = 1; res < n; res <<= 1)
      ;
    return res;
  }
  T sub(int l, int r, int node, int lb, int ub) {
    if (ub <= l || r <= lb)
      return id;
    if (l <= lb && ub <= r)
      return data[node];
    return merge(sub(l, r, node * 2, lb, (lb + ub) / 2),
                 sub(l, r, node * 2 + 1, (lb + ub) / 2, ub));
  }

public:
  SegmentTree(int n_, T id_) : n(size(n_)), id(id_), data(size(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) { return sub(l, r + 1, 1, 0, n); }
};

template <typename T> class SegmentTree2 {
  const int h;
  const T id;
  vector<SegmentTree<T>> data;
  int size(int n) {
    int res;
    for (res = 1; res < n; res <<= 1)
      ;
    return res;
  }
  T sub(int li, int lj, int ri, int rj, int node, int lb, int ub) {
    if (ub <= li || ri <= lb)
      return id;
    if (li <= lb && ub <= ri)
      return data[node].Find(lj, rj - 1);
    return merge(sub(li, lj, ri, rj, node * 2, lb, (lb + ub) / 2),
                 sub(li, lj, ri, rj, node * 2 + 1, (lb + ub) / 2, ub));
  }

public:
  SegmentTree2(int h_, int w_, T id_)
      : h(size(h_)), id(id_), data(h * 2, SegmentTree<T>(w_, id)) {}
  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, j), data[i * 2 + 1].Find(j, j)));
  }
  T Find(int i, int j) { return data[i + h].Find(j); }
  T Find(int li, int lj, int ri, int rj) {
    return sub(li, lj, ri + 1, rj + 1, 1, 0, h);
  }
};

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) {
    SegmentTree2<int> st(r, c, INT_MAX);
    {
      vector<vector<int>> grid(r, vector<int>(c));
      for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
          cin >> grid[i][j];
        }
      }
      st.Init(grid);
    }
    while (q--) {
      cin >> r1 >> c1 >> r2 >> c2;
      printf("%d\\n", st.Find(r1, c1, r2, c2));
    }
  }
  return 0;
}