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

#include <algorithm>
#include <stdio.h>
#include <string.h>

using namespace std;

typedef long long LL;

#define INF 0x7fffffff
#define MAX 1048576
#define MAXN 65535
#define MAXLg 16
#define MAXQ 20000

int A[MAX], Log[MAXN + 1], tableMin[MAXN][MAXLg];

void makeRMinQ(int *a, int s, int t) {
  int n = t - s;
  for (int i = s; i < t; ++i)
    tableMin[i - s][0] = a[i];
  for (int j = 1; (1 << j) <= n; ++j)
    for (int i = s; i + (1 << j) <= t; ++i)
      tableMin[i - s][j] =
          min(tableMin[i - s][j - 1], tableMin[i - s + (1 << (j - 1))][j - 1]);
}

int QueryMin(int x, int y) {
  int p = Log[y - x + 1];
  return min(tableMin[x][p], tableMin[y - (1 << p) + 1][p]);
}

struct query {
  int x1, y1;
  int x2, y2;
} fQ[MAXQ];

int Res[MAXQ];

int main() {
  for (int i = 0, x = 0, cd = 2; i <= MAXN; ++x, cd <<= 1)
    while (i <= MAXN && i < cd)
      Log[++i] = x;
  int R, C, Q;
  while (scanf("%d%d%d", &R, &C, &Q), R) {
    if (R <= C) {
      for (int i = 0; i < R; ++i)
        for (int j = 0; j < C; ++j)
          scanf("%d", &A[i * C + j]);
      for (int q = 0; q < Q; ++q)
        scanf("%d%d%d%d", &fQ[q].x1, &fQ[q].y1, &fQ[q].x2, &fQ[q].y2);
    } else {
      for (int i = 0; i < R; ++i)
        for (int j = 0; j < C; ++j)
          scanf("%d", &A[j * R + i]);
      swap(R, C);
      for (int q = 0; q < Q; ++q) {
        scanf("%d%d%d%d", &fQ[q].x1, &fQ[q].y1, &fQ[q].x2, &fQ[q].y2);
        swap(fQ[q].x1, fQ[q].y1);
        swap(fQ[q].x2, fQ[q].y2);
      }
    }
    for (int q = 0; q < Q; ++q)
      Res[q] = INF;
    int fC = (C - 1) / MAXN + 1;
    for (int i = 0; i < R; ++i) {
      for (int j = 0, k = 0; j < fC; ++j) {
        int nk = min(C, k + MAXN);
        makeRMinQ(A, i * C + k, i * C + nk);
        for (int q = 0; q < Q; ++q) {
          if (i < fQ[q].x1 || fQ[q].x2 < i)
            continue;
          int cs = max(fQ[q].y1, k);
          int ct = min(fQ[q].y2, nk - 1);
          if (cs > ct)
            continue;
          Res[q] = min(Res[q], QueryMin(cs - k, ct - k));
        }
        k = nk;
      }
    }
    for (int q = 0; q < Q; ++q)
      printf("%d\\n", Res[q]);
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 1000010;
const int inf = 0x7fffffff;
struct Tree {
  int x[2];
  int y[2];
  int val;
  int son[4];
} tt[N * 2];
int a[N];
int n, m;
int loc;
void build(int x0, int x1, int y0, int y1, int idx) {
  tt[idx].x[0] = x0;
  tt[idx].x[1] = x1;
  tt[idx].y[0] = y0;
  tt[idx].y[1] = y1;
  for (int i = 0; i < 4; i++) {
    tt[idx].son[i] = 0;
  }
  if (x0 == x1 && y0 == y1) {
    tt[idx].val = a[(x0 - 1) * m + y0];
    return;
  }
  int mx = (x0 + x1) >> 1;
  int my = (y0 + y1) >> 1;
  if (x0 == x1) {
    tt[idx].son[0] = ++loc;
    tt[idx].son[1] = ++loc;
    build(x0, x0, y0, my, tt[idx].son[0]);
    build(x0, x0, my + 1, y1, tt[idx].son[1]);
    tt[idx].val = min(tt[tt[idx].son[0]].val, tt[tt[idx].son[1]].val);
  } else if (y0 == y1) {
    tt[idx].son[0] = ++loc;
    tt[idx].son[2] = ++loc;
    build(x0, mx, y0, y0, tt[idx].son[0]);
    build(mx + 1, x1, y0, y0, tt[idx].son[2]);
    tt[idx].val = min(tt[tt[idx].son[0]].val, tt[tt[idx].son[2]].val);
  } else {
    tt[idx].son[0] = ++loc;
    tt[idx].son[1] = ++loc;
    tt[idx].son[2] = ++loc;
    tt[idx].son[3] = ++loc;
    build(x0, mx, y0, my, tt[idx].son[0]);
    build(x0, mx, my + 1, y1, tt[idx].son[1]);
    build(mx + 1, x1, y0, my, tt[idx].son[2]);
    build(mx + 1, x1, my + 1, y1, tt[idx].son[3]);
    tt[idx].val = min(tt[tt[idx].son[0]].val, tt[tt[idx].son[1]].val);
    tt[idx].val = min(tt[idx].val, tt[tt[idx].son[2]].val);
    tt[idx].val = min(tt[idx].val, tt[tt[idx].son[3]].val);
  }
}
int query(int x0, int x1, int y0, int y1, int idx) {
  if (tt[idx].x[0] >= x0 && tt[idx].x[1] <= x1 && tt[idx].y[0] >= y0 &&
      tt[idx].y[1] <= y1) {
    return tt[idx].val;
  }
  if (tt[idx].x[0] > x1 || tt[idx].x[1] < x0 || tt[idx].y[0] > y1 ||
      tt[idx].y[1] < y0) {
    return inf;
  }
  int ans = inf;
  for (int i = 0; i < 4; i++) {
    if (tt[idx].son[i] != 0) {
      ans = min(query(x0, x1, y0, y1, tt[idx].son[i]), ans);
    }
  }
  return ans;
}
int main(void) {
  int q, x0, x1, y0, y1;
  while (scanf("%d%d%d", &n, &m, &q) && (n || m || q)) {
    for (int i = 1; i <= n * m; i++) {
      scanf("%d", &a[i]);
    }
    loc = 1;
    build(1, n, 1, m, 1);
    for (int i = 1; i <= q; i++) {
      scanf("%d%d%d%d", &x0, &y0, &x1, &y1);
      x0++;
      y0++;
      x1++;
      y1++;
      printf("%d\\n", query(x0, x1, y0, y1, 1));
    }
  }
  return 0;
}