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

#include <algorithm>
#include <climits>
#include <functional>
#include <iostream>

using namespace std;

template <class S = int, class T = std::less<S>, S nil = INT_MAX> class RMQ {
  friend class RMQ2D;

  static int calcsize(int n) {
    int res = 1;
    while (res < n)
      res <<= 1;
    return res;
  }
  RMQ() {}
  ~RMQ() {}
  void build(int n, const S a[], S *dat) {
    int m = n;
    n = calcsize(n);
    // dat=new S[2*n-1];
    for (int i = 0; i < m; i++)
      dat[n - 1 + i] = a[i];
    for (int i = m; i < n; i++)
      dat[n - 1 + i] = nil;
    for (int i = n - 2; i >= 0; i--) {
      dat[i] = std::min(dat[i * 2 + 1], dat[i * 2 + 2], T());
    }
  }
  /*void update(int k,int a){//k番目をaに変更
          k+=n-1;
          dat[k]=a;
          while(k>0){
                  k=(k-1)/2;
                  dat[k]=std::min(dat[k*2+1],dat[k*2+2],T());
          }
  }*/
  S query(const S *dat, int a, int b, int k, int l,
          int r) const { //[a,b)の最小(大)値
    if (r <= a || b <= l)
      return nil;
    if (a <= l && r <= b)
      return dat[k];
    else {
      S vl = query(dat, a, b, k * 2 + 1, l, (l + r) / 2);
      S vr = query(dat, a, b, k * 2 + 2, (l + r) / 2, r);
      return std::min(vl, vr, T());
    }
  }
};

class RMQ2D {
  typedef unsigned int S;
  typedef std::less<S> T;
  static const S nil = ~0u;
  int h, w;
  S *datrmq;
  RMQ<S, T, nil> *rmq;
  int query(int a, int b, int k, int l, int r, int xs, int xe) const {
    if (r <= a || b <= l)
      return nil;
    if (a <= l && r <= b)
      return rmq[k].query(datrmq + k * (2 * w - 1), xs, xe, 0, 0, w);
    else {
      S vl = query(a, b, k * 2 + 1, l, (l + r) / 2, xs, xe);
      S vr = query(a, b, k * 2 + 2, (l + r) / 2, r, xs, xe);
      return std::min(vl, vr);
    }
  }

public:
  RMQ2D(int h, int w, const S a[]) {
    S *dat;
    int n = h, m = w;
    h = this->h = RMQ<S, T, nil>::calcsize(h);
    w = this->w = RMQ<S, T, nil>::calcsize(w);
    datrmq = new S[(2 * h - 1) * (2 * w - 1)];
    dat = new S[2 * w - 1];
    for (int i = 0; i < w; i++)
      dat[i] = nil;
    rmq = new RMQ<S, T, nil>[2 * h - 1];

    for (int i = 0; i < n; i++)
      rmq[h - 1 + i].build(m, a + i * m, datrmq + (h - 1 + i) * (2 * w - 1));
    for (int i = n; i < h; i++)
      rmq[h - 1 + i].build(m, dat, datrmq + (h - 1 + i) * (2 * w - 1));
    for (int i = h - 2; i >= 0; i--) {
      rmq[i].build(m, dat, datrmq + i * (2 * w - 1));
      for (int j = 0; j < 2 * w - 1; j++) {
        S *a = datrmq + (i * 2 + 1) * (2 * w - 1);
        S *b = datrmq + (i * 2 + 2) * (2 * w - 1);
        datrmq[i * (2 * w - 1) + j] = std::min(a[j], b[j]);
        // rmq[i].dat[j]=std::min(rmq[i*2+1].dat[j],rmq[i*2+2].dat[j],T());
      }
    }
    delete[] dat;
  }
  ~RMQ2D() {
    delete[] rmq;
    delete[] datrmq;
  }
  void update(int y, int x, int a) {
    // 「あとで」
  }
  int query(int ys, int ye, int xs,
            int xe) const { //[ys,ye)+[xs,xe)の最小(大)値
    return query(ys, ye, 0, 0, h, xs, xe);
  }
};

unsigned int g[1000000];
int main() {
  int r, c, q;
  while (cin >> r >> c >> q, r | c | q) {
    for (int i = 0; i < r * c; i++)
      cin >> g[i];
    RMQ2D rmq(r, c, g);
    for (int i = 0; i < q; i++) {
      int y1, x1, y2, x2;
      cin >> y1 >> x1 >> y2 >> x2;
      cout << rmq.query(y1, y2 + 1, x1, x2 + 1) << endl;
    }
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <functional>
#include <iostream>

using namespace std;

template <class S = int, class T = std::less<S>, S nil = INT_MAX> class RMQ {
  friend class RMQ2D;
  S *dat;

  static int calcsize(int n) {
    int res = 1;
    while (res < n)
      res <<= 1;
    return res;
  }

public:
  RMQ() : dat(0) {}
  ~RMQ() { delete[] dat; }
  void build(int n, const S a[]) {
    int m = n;
    n = calcsize(n);
    dat = new S[2 * n - 1];
    for (int i = 0; i < m; i++)
      dat[n - 1 + i] = a[i];
    for (int i = m; i < n; i++)
      dat[n - 1 + i] = nil;
    for (int i = n - 2; i >= 0; i--) {
      dat[i] = std::min(dat[i * 2 + 1], dat[i * 2 + 2], T());
    }
  }
  /*void update(int k,int a){//k番目をaに変更
          k+=n-1;
          dat[k]=a;
          while(k>0){
                  k=(k-1)/2;
                  dat[k]=std::min(dat[k*2+1],dat[k*2+2],T());
          }
  }*/
  S query(int a, int b, int k, int l, int r) const { //[a,b)の最小(大)値
    if (r <= a || b <= l)
      return nil;
    if (a <= l && r <= b)
      return dat[k];
    else {
      S vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      S vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return std::min(vl, vr, T());
    }
  }
};

class RMQ2D {
  typedef unsigned int S;
  typedef std::less<S> T;
  static const S nil = ~0u;
  int h, w;
  RMQ<S, T, nil> *rmq;
  int query(int a, int b, int k, int l, int r, int xs, int xe) const {
    if (r <= a || b <= l)
      return nil;
    if (a <= l && r <= b)
      return rmq[k].query(xs, xe, 0, 0, w);
    else {
      S vl = query(a, b, k * 2 + 1, l, (l + r) / 2, xs, xe);
      S vr = query(a, b, k * 2 + 2, (l + r) / 2, r, xs, xe);
      return std::min(vl, vr);
    }
  }

public:
  RMQ2D(int h, int w, const S a[]) {
    S *dat;
    int n = h, m = w;
    h = this->h = RMQ<S, T, nil>::calcsize(h);
    w = this->w = RMQ<S, T, nil>::calcsize(w);
    dat = new S[2 * w - 1];
    for (int i = 0; i < w; i++)
      dat[i] = nil;
    rmq = new RMQ<S, T, nil>[2 * h - 1];
    for (int i = 0; i < n; i++)
      rmq[h - 1 + i].build(m, a + i * m);
    for (int i = n; i < h; i++)
      rmq[h - 1 + i].build(m, dat);
    for (int i = h - 2; i >= 0; i--) {
      rmq[i].build(m, dat);
      for (int j = 0; j < 2 * w - 1; j++)
        rmq[i].dat[j] =
            std::min(rmq[i * 2 + 1].dat[j], rmq[i * 2 + 2].dat[j], T());
    }
    delete[] dat;
  }
  ~RMQ2D() { delete[] rmq; }
  void update(int y, int x, int a) {
    // 「あとで」
  }
  int query(int ys, int ye, int xs,
            int xe) const { //[ys,ye)+[xs,xe)の最小(大)値
    return query(ys, ye, 0, 0, h, xs, xe);
  }
};

unsigned int g[1000000];
int main() {
  int r, c, q;
  while (cin >> r >> c >> q, r | c | q) {
    for (int i = 0; i < r * c; i++)
      cin >> g[i];
    RMQ2D rmq(r, c, g);
    for (int i = 0; i < q; i++) {
      int y1, x1, y2, x2;
      cin >> y1 >> x1 >> y2 >> x2;
      cout << rmq.query(y1, y2 + 1, x1, x2 + 1) << endl;
    }
  }
  return 0;
}