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

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 2147483647

class RMQ {
public:
  RMQ(int height, int first_N) {
    rmq_H = height;
    N = 1;
    while (N < first_N)
      N *= 2;
    table = new int *[height];
    for (int row = 0; row < height; row++) {
      table[row] = new int[2 * N - 1];
      for (int col = 0; col < 2 * N - 1; col++) {
        table[row][col] = NUM;
      }
    }
  }

  void update(int row, int loc, int value) {
    loc += N - 1;

    table[row][loc] = value;

    if (N == 1)
      return;

    int parent = (loc - 1) / 2;

    while (true) {
      table[row][parent] =
          min(table[row][2 * parent + 1], table[row][2 * parent + 2]);

      if (parent == 0)
        break;
      else {
        parent = (parent - 1) / 2;
      }
    }
  }

  int getN() { return N; }

  int query(int row, int search_left, int search_right, int node_id,
            int node_left, int node_right) {

    if (search_right < node_left || search_left > node_right)
      return NUM;

    if (search_left <= node_left && search_right >= node_right) {
      return table[row][node_id];
    }

    int left_min = query(row, search_left, search_right, 2 * node_id + 1,
                         node_left, (node_left + node_right) / 2);
    int right_min = query(row, search_left, search_right, 2 * node_id + 2,
                          (node_left + node_right) / 2 + 1, node_right);

    return min(left_min, right_min);
  }

  int **table;
  int N, rmq_H;
};

int H, W, Q;

void func() {

  int **input = new int *[H];
  for (int row = 0; row < H; row++) {
    input[row] = new int[W];
  }

  for (int row = 0; row < H; row++) {
    for (int col = 0; col < W; col++)
      scanf("%d", &input[row][col]);
  }

  if (W >= H) {
    RMQ YOKO(H, W);
    for (int row = 0; row < H; row++) {
      for (int col = 0; col < W; col++) {
        YOKO.update(row, col, input[row][col]);
      }
    }

    int row1, col1, row2, col2;
    int ans;

    for (int loop = 0; loop < Q; loop++) {
      scanf("%d %d %d %d", &row1, &col1, &row2, &col2);

      ans = NUM;

      for (int row = row1; row <= row2; row++) {
        ans = min(ans, YOKO.query(row, col1, col2, 0, 0, YOKO.getN() - 1));
      }
      printf("%d\\n", ans);
    }
  } else {

    RMQ TATE(W, H);
    for (int col = 0; col < W; col++) {
      for (int row = 0; row < H; row++) {
        TATE.update(col, row, input[row][col]);
      }
    }

    int row1, col1, row2, col2;
    int ans;

    for (int loop = 0; loop < Q; loop++) {
      scanf("%d %d %d %d", &row1, &col1, &row2, &col2);

      ans = NUM;

      for (int col = col1; col <= col2; col++) {
        ans = min(ans, TATE.query(col, row1, row2, 0, 0, TATE.getN() - 1));
      }
      printf("%d\\n", ans);
    }
  }
}

int main() {

  while (true) {
    scanf("%d %d %d", &H, &W, &Q);
    if (H == 0 && W == 0 && Q == 0)
      break;

    func();
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 2147483647

class RMQ {
public:
  RMQ(int height, int first_N) {
    rmq_H = height;
    N = 1;
    while (N < first_N)
      N *= 2;
    table = new int *[height];
    for (int row = 0; row < height; row++) {
      table[row] = new int[2 * N - 1];
      for (int col = 0; col < 2 * N - 1; col++) {
        table[row][col] = NUM;
      }
    }
  }

  void update(int row, int loc, int value) {
    loc += N - 1;

    table[row][loc] = value;

    if (N == 1)
      return;

    int parent = (loc - 1) / 2;

    while (true) {
      table[row][parent] =
          min(table[row][2 * parent + 1], table[row][2 * parent + 2]);

      if (parent == 0)
        break;
      else {
        parent = (parent - 1) / 2;
      }
    }
  }

  int getN() { return N; }

  int query(int row, int search_left, int search_right, int node_id,
            int node_left, int node_right) {

    if (search_right < node_left || search_left > node_right)
      return NUM;

    if (search_left <= node_left && search_right >= node_right) {
      return table[row][node_id];
    }

    int left_min = query(row, search_left, search_right, 2 * node_id + 1,
                         node_left, (node_left + node_right) / 2);
    int right_min = query(row, search_left, search_right, 2 * node_id + 2,
                          (node_left + node_right) / 2 + 1, node_right);

    return min(left_min, right_min);
  }

  void FREE() {
    for (int row = 0; row < rmq_H; row++) {
      delete[] table[row];
    }
    delete[] table;
  }

  int **table;
  int N, rmq_H;
};

int H, W, Q;

void func() {

  int **input = new int *[H];
  for (int row = 0; row < H; row++) {
    input[row] = new int[W];
  }

  for (int row = 0; row < H; row++) {
    for (int col = 0; col < W; col++)
      scanf("%d", &input[row][col]);
  }

  RMQ YOKO(H, W);
  for (int row = 0; row < H; row++) {
    for (int col = 0; col < W; col++) {
      YOKO.update(row, col, input[row][col]);
    }
  }

  RMQ TATE(W, H);
  for (int col = 0; col < W; col++) {
    for (int row = 0; row < H; row++) {
      TATE.update(col, row, input[row][col]);
    }
  }

  for (int row = 0; row < H; row++) {
    delete[] input[row];
  }
  delete[] input;

  int row1, col1, row2, col2;
  int ans;

  for (int loop = 0; loop < Q; loop++) {
    scanf("%d %d %d %d", &row1, &col1, &row2, &col2);

    ans = NUM;

    if (row2 - row1 >= col2 - col1) {
      for (int col = col1; col <= col2; col++) {
        ans = min(ans, TATE.query(col, row1, row2, 0, 0, TATE.getN() - 1));
      }
    } else {
      for (int row = row1; row <= row2; row++) {
        ans = min(ans, YOKO.query(row, col1, col2, 0, 0, YOKO.getN() - 1));
      }
    }
    printf("%d\\n", ans);
  }

  YOKO.FREE();
  TATE.FREE();
}

int main() {

  while (true) {
    scanf("%d %d %d", &H, &W, &Q);
    if (H == 0 && W == 0 && Q == 0)
      break;

    func();
  }

  return 0;
}