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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>

using namespace std;

#define dump(n) cout << "# " << #n << "=" << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define iter(c) __typeof__((c).begin())
#define foreach(i, c) for (iter(c) i = (c).begin(); i != (c).end(); ++i)
#define all(c) (c).begin(), (c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int INFTY = INT_MAX;
const double EPS = 1e-9;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '[';
  rep(i, a.size()) os << (i ? " " : "") << a[i];
  return os << ']';
}

int Need(int size) {
  size--;
  rep(i, 5) size |= size >> (1 << i);
  return size + 1;
}

struct SegTree {
  int size;
  vi data;
  SegTree(int s) : size(Need(s)), data(size * 2, INFTY) {}
  void Update(int i, int x) {
    for (i += size; i; i >>= 1)
      data[i] = min(data[i], x);
  }
  int Query(int a, int b, int i, int l, int r) {
    if (b <= l || r <= a)
      return INFTY;
    if (a <= l && r <= b)
      return data[i];
    int res = INFTY, m = (l + r) / 2;
    if (a < m)
      res = min(res, Query(a, b, i * 2 + 0, l, m));
    if (m < b)
      res = min(res, Query(a, b, i * 2 + 1, m, r));
    return res;
  }
  int Query(int a, int b) { return Query(a, b, 1, 0, size); }
};

struct SegTree2D {
  int size;
  vector<SegTree> data;
  SegTree2D(int h, int w) : size(Need(h)), data(size * 2, SegTree(w)) {}
  void Update(int i, int j, int x) {
    for (i += size; i; i >>= 1)
      data[i].Update(j, x);
  }
  int Query(int a, int b, int c, int d, int i, int to, int bo) {
    if (c <= to || bo <= a)
      return INFTY;
    if (a <= to && bo <= c)
      return data[i].Query(b, d);
    int res = INFTY, m = (to + bo) / 2;
    if (a < m)
      res = min(res, Query(a, b, c, d, i * 2 + 0, to, m));
    if (m < c)
      res = min(res, Query(a, b, c, d, i * 2 + 1, m, bo));
    return res;
  }
  int Query(int a, int b, int c, int d) {
    return Query(a, b, c, d, 1, 0, size);
  }
};

int main() {
  for (int r, c, q; scanf("%d%d%d", &r, &c, &q), r | c | q;) {
    vvi grid(min(r, c), vi(max(r, c)));
    if (r <= c)
      rep(i, r) rep(j, c) scanf("%d", &grid[i][j]);
    else
      rep(j, r) rep(i, c) scanf("%d", &grid[i][j]);

    vi r1(q), c1(q), r2(q), c2(q);
    rep(i, q) scanf("%d%d%d%d", &r1[i], &c1[i], &r2[i], &c2[i]);

    if (r > c) {
      swap(r, c);
      swap(r1, c1);
      swap(r2, c2);
    }

    SegTree2D st(r, c);
    rep(i, r) rep(j, c) st.Update(i, j, grid[i][j]);

    rep(i, q) printf("%d\\n", st.Query(r1[i], c1[i], r2[i] + 1, c2[i] + 1));
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>

using namespace std;

#define dump(n) cout << "# " << #n << "=" << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define iter(c) __typeof__((c).begin())
#define foreach(i, c) for (iter(c) i = (c).begin(); i != (c).end(); ++i)
#define all(c) (c).begin(), (c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int INFTY = INT_MAX;
const double EPS = 1e-9;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '[';
  rep(i, a.size()) os << (i ? " " : "") << a[i];
  return os << ']';
}

int Need(int size) {
  size--;
  rep(i, 5) size |= size >> (1 << i);
  return size + 1;
}

struct SegTree {
  int size;
  vi data;
  SegTree(int s) : size(Need(s)), data(size * 2, INFTY) {}
  void Update(int i, int x) {
    for (i += size; i; i >>= 1)
      data[i] = min(data[i], x);
  }
  int Query(int a, int b, int i, int l, int r) {
    if (b <= l || r <= a)
      return INFTY;
    if (a <= l && r <= b)
      return data[i];
    int res = INFTY, m = (l + r) / 2;
    if (a < m)
      res = min(res, Query(a, b, i * 2 + 0, l, m));
    if (m < b)
      res = min(res, Query(a, b, i * 2 + 1, m, r));
    return res;
  }
  int Query(int a, int b) { return Query(a, b, 1, 0, size); }
};

struct SegTree2D {
  int size;
  vector<SegTree> data;
  SegTree2D(int h, int w) : size(Need(h)), data(size * 2, SegTree(w)) {}
  void Update(int i, int j, int x) {
    for (i += size; i; i >>= 1)
      data[i].Update(j, x);
  }
  int Query(int a, int b, int c, int d, int i, int to, int bo) {
    if (c <= to || bo <= a)
      return INFTY;
    if (a <= to && bo <= c)
      return data[i].Query(b, d);
    int res = INFTY, m = (to + bo) / 2;
    if (a < m)
      res = min(res, Query(a, b, c, d, i * 2 + 0, to, m));
    if (m < c)
      res = min(res, Query(a, b, c, d, i * 2 + 1, m, bo));
    return res;
  }
  int Query(int a, int b, int c, int d) {
    return Query(a, b, c, d, 1, 0, size);
  }
};

int main() {
  for (int r, c, q; scanf("%d%d%d", &r, &c, &q), r | c | q;) {
    vvi grid(r, vi(c));
    rep(i, r) rep(j, c) scanf("%d", &grid[i][j]);

    SegTree2D st(r, c);
    rep(i, r) rep(j, c) st.Update(i, j, grid[i][j]);

    while (q--) {
      int r1, c1, r2, c2;
      scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
      printf("%d\\n", st.Query(r1, c1, r2 + 1, c2 + 1));
    }
  }

  return 0;
}