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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;
#define SZ(v) ((int)(v).size())
const int maxint = -1u >> 1;
const int maxn = 1000000 + 40;

int r, c, q;
int t[maxn * 4], a[maxn];

inline int to(int x, int y, int c) { return x * c + y; }
int build(int x, int n, int lf, int rt) {
  if (lf == rt) {
    return t[to(x, n, c * 4)] = a[to(x, lf, c)];
  }
  int mid = (lf + rt) / 2;
  return t[to(x, n, c * 4)] =
             min(build(x, n * 2, lf, mid), build(x, n * 2 + 1, mid + 1, rt));
}

int query(int x, int n, int lf, int rt, int x1, int x2) {
  // printf("%d %d\\n", x1, x2);
  if (lf == x1 && rt == x2) {
    // printf("%d %d %d: %d\\n", x, n, c * 4, to(x, n, c * 4));
    return t[to(x, n, c * 4)];
  }
  int mid = (lf + rt) / 2;
  if (mid >= x2) {
    return query(x, n * 2, lf, mid, x1, x2);
  } else if (mid < x1) {
    return query(x, n * 2 + 1, mid + 1, rt, x1, x2);
  }
  return min(query(x, n * 2, lf, mid, x1, mid),
             query(x, n * 2 + 1, mid + 1, rt, mid + 1, x2));
}

void gao() {
  bool f = false;
  if (r > c) {
    swap(r, c);
    f = true;
    for (int i = 0; i < c; ++i) {
      for (int j = 0; j < r; ++j) {
        scanf("%d", &a[to(j, i, c)]);
      }
    }
  } else {
    for (int i = 0; i < r; ++i) {
      for (int j = 0; j < c; ++j) {
        scanf("%d", &a[to(i, j, c)]);
      }
    }
  }
  for (int i = 0; i < r; ++i) {
    build(i, 1, 0, c - 1);
  }
  while (q--) {
    int r1, c1, r2, c2;
    scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
    if (f)
      swap(r1, c1), swap(r2, c2);
    int ans = query(r1, 1, 0, c - 1, c1, c2);
    for (int i = r1 + 1; i <= r2; ++i) {
      ans = min(ans, query(i, 1, 0, c - 1, c1, c2));
    }
    printf("%d\\n", ans);
  }
}

int main() {
  while (scanf("%d%d%d", &r, &c, &q), r || c || q) {
    gao();
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;

const int maxn = 1000000 * 3;

vector<int> A[1000009];
int n;
struct node {
  int x1, x2, y1, y2;
  int min;
  int ch[4];
};
node tree[maxn];

int tol;

void maketree(int x1, int x2, int y1, int y2) {
  int k = ++tol;
  tree[k].x1 = x1;
  tree[k].x2 = x2;
  tree[k].y1 = y1;
  tree[k].y2 = y2;
  tree[k].min = 0;
  if (x1 == x2 && y1 == y2) {
    tree[k].min = A[x1][y1];
    memset(tree[k].ch, 0, sizeof(tree[k].ch));
    return;
  }

  int midx = (x1 + x2) >> 1;
  int midy = (y1 + y2) >> 1;

  tree[k].ch[0] = tol + 1;
  maketree(x1, midx, y1, midy);

  if (midx + 1 <= x2 && midy + 1 <= y2) {
    tree[k].ch[1] = tol + 1;
    maketree(midx + 1, x2, midy + 1, y2);
  } else
    tree[k].ch[1] = 0;

  if (midy + 1 <= y2) {
    tree[k].ch[2] = tol + 1;
    maketree(x1, midx, midy + 1, y2);
  } else
    tree[k].ch[2] = 0;

  if (midx + 1 <= x2) {
    tree[k].ch[3] = tol + 1;
    maketree(midx + 1, x2, y1, midy);
  } else
    tree[k].ch[3] = 0;

  tree[k].min = tree[tree[k].ch[0]].min;
  for (int i = 1; i < 4; i++)
    if (tree[k].ch[i])
      tree[k].min = min(tree[k].min, tree[tree[k].ch[i]].min);
}

inline bool cross(int x1, int x2, int y1, int y2, int k) {
  if (x2 < tree[k].x1 || tree[k].x2 < x1 || y2 < tree[k].y1 || tree[k].y2 < y1)
    return false;
  return true;
}

int Query(int x1, int x2, int y1, int y2, int k) {
  if (cross(x1, x2, y1, y2, k) == 0)
    return INT_MAX;

  if (x1 <= tree[k].x1 && tree[k].x2 <= x2 && y1 <= tree[k].y1 &&
      tree[k].y2 <= y2)
    return tree[k].min;
  int minx = Query(x1, x2, y1, y2, tree[k].ch[0]);

  for (int i = 1; i < 4; i++)
    minx = min(minx, Query(x1, x2, y1, y2, tree[k].ch[i]));
  return minx;
}

int main() {
  int r, c, q, temp;
  int x1, y1, x2, y2;
  while ((scanf("%d%d%d", &r, &c, &q), r)) {
    for (int i = 1; i <= r; i++) {
      if (A[i].size() <= 1)
        A[i].push_back(0);
      for (int j = 1; j <= c; j++) {
        scanf("%d", &temp);
        if (j >= A[i].size()) {
          A[i].push_back(temp);
        } else {
          A[i][j] = temp;
        }
      }
    }
    tol = 0;
    maketree(1, r, 1, c);
    while (q--) {
      scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
      x1++, y1++, x2++, y2++;
      printf("%d\\n", Query(x1, x2, y1, y2, 1));
    }
  }
}