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

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

#define REP2(i, m, n) for (int i = (int)(m); i < (int)(n); i++)
#define REP(i, n) REP2(i, 0, n)
#define ALL(c) (c).begin(), (c).end()
#define ITER(c) __typeof((c).begin())
#define PB(e) push_back(e)
#define FOREACH(i, c) for (ITER(c) i = (c).begin(); i != (c).end(); ++i)
#define MP(a, b) make_pair(a, b)
#define PARITY(n) ((n)&1)

typedef long long ll;
typedef pair<ll, ll> P;
typedef unsigned int uint;

const uint INF = (uint)1 << 31;
const int sz = 1000010;
uint field[sz];
uint dat[sz * 20];
int R, C, Q;

#define FIELD(r, c) (field[(r)*C + (c)])
#define DAT(kr, kc) (dat[(kr) * (C)*4 + (kc)])

void build(int lr, int rr, int lc, int rc, int kr, int kc, bool r_axis = true) {
  if (rr - lr == 1 && rc - lc == 1) {
    DAT(kr, kc) = FIELD(lr, lc);
  } else if ((r_axis && rr - lr > 1) || rc - lc == 1) {
    assert(rr - lr != 1);
    int mr = (lr + rr) / 2;
    build(lr, mr, lc, rc, kr * 2 + 1, kc, false);
    build(mr, rr, lc, rc, kr * 2 + 2, kc, false);
    DAT(kr, kc) = min(DAT(kr * 2 + 1, kc), DAT(kr * 2 + 2, kc));

  } else {
    int mc = (lc + rc) / 2;
    build(lr, rr, lc, mc, kr, kc * 2 + 1, true);
    build(lr, rr, mc, rc, kr, kc * 2 + 2, true);
    DAT(kr, kc) = min(DAT(kr, kc * 2 + 1), DAT(kr, kc * 2 + 2));
  }
}

uint query(int ar, int br, int ac, int bc, int lr = 0, int rr = R, int lc = 0,
           int rc = C, int kr = 0, int kc = 0, bool r_axis = true) {
  if (rr <= ar || br <= lr || rc <= ac || bc <= lc || rr <= lr || rc <= lc)
    return INF;

  if (ar <= lr && rr <= br && ac <= lc && rc <= bc) {
    return DAT(kr, kc);
  } else if ((r_axis && rr - lr > 1) || rc - lc == 1) {
    int mr = (lr + rr) / 2;
    return min(query(ar, br, ac, bc, lr, mr, lc, rc, kr * 2 + 1, kc, false),
               query(ar, br, ac, bc, mr, rr, lc, rc, kr * 2 + 2, kc, false));
  } else {
    int mc = (lc + rc) / 2;
    return min(query(ar, br, ac, bc, lr, rr, lc, mc, kr, kc * 2 + 1, true),
               query(ar, br, ac, bc, lr, rr, mc, rc, kr, kc * 2 + 2, true));
  }
}

uint naive(int ar, int br, int ac, int bc) {
  uint ans = INF;
  REP2(i, ar, br) REP2(j, ac, bc) ans = min(ans, FIELD(i, j));
  return ans;
}

int main() {
  int r1, r2, c1, c2;
  while (scanf("%d%d%d", &R, &C, &Q) != EOF) {

    REP(r, R) REP(c, C) scanf("%d", &FIELD(r, c));
    if (R > 0 && C > 0)
      build(0, R, 0, C, 0, 0);
    REP(q, Q) {
      scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
      printf("%u\\n", query(r1, r2 + 1, c1, c2 + 1));
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

#define REP2(i, m, n) for (int i = (int)(m); i < (int)(n); i++)
#define REP(i, n) REP2(i, 0, n)
#define ALL(c) (c).begin(), (c).end()
#define ITER(c) __typeof((c).begin())
#define PB(e) push_back(e)
#define FOREACH(i, c) for (ITER(c) i = (c).begin(); i != (c).end(); ++i)
#define MP(a, b) make_pair(a, b)
#define PARITY(n) ((n)&1)

typedef long long ll;
typedef pair<ll, ll> P;
typedef unsigned int uint;

#define DEBUG

const uint INF = (uint)1 << 31;
const int sz = 1000010;
uint field[sz];
uint dat[sz * 20];
int R, C, Q;

#define FIELD(r, c) (field[(r)*C + (c)])
#define DAT(kr, kc) (dat[(kr) * (C)*4 + (kc)])

void build(int lr, int rr, int lc, int rc, int kr, int kc, bool r_axis = true) {
  if (rr - lr == 1 && rc - lc == 1) {
    DAT(kr, kc) = FIELD(lr, lc);
  } else if ((r_axis && rr - lr > 1) || rc - lc == 1) {
    assert(rr - lr != 1);
    int mr = (lr + rr) / 2;
    build(lr, mr, lc, rc, kr * 2 + 1, kc, false);
    build(mr, rr, lc, rc, kr * 2 + 2, kc, false);
    DAT(kr, kc) = min(DAT(kr * 2 + 1, kc), DAT(kr * 2 + 2, kc));

  } else {
    int mc = (lc + rc) / 2;
    build(lr, rr, lc, mc, kr, kc * 2 + 1, true);
    build(lr, rr, mc, rc, kr, kc * 2 + 2, true);
    DAT(kr, kc) = min(DAT(kr, kc * 2 + 1), DAT(kr, kc * 2 + 2));
  }
}

uint query(int ar, int br, int ac, int bc, int lr = 0, int rr = R, int lc = 0,
           int rc = C, int kr = 0, int kc = 0, bool r_axis = true) {
  if (rr <= ar || br <= lr || rc <= ac || bc <= lc || rr <= lr || rc <= lc)
    return INF;

  if (ar <= lr && rr <= br && ac <= lc && rc <= bc) {
    return DAT(kr, kc);
  } else if ((r_axis && rr - lr > 1) || rc - lc == 1) {
    int mr = (lr + rr) / 2;
    return min(query(ar, br, ac, bc, lr, mr, lc, rc, kr * 2 + 1, kc, false),
               query(ar, br, ac, bc, mr, rr, lc, rc, kr * 2 + 2, kc, false));
  } else {
    int mc = (lc + rc) / 2;
    return min(query(ar, br, ac, bc, lr, rr, lc, mc, kr, kc * 2 + 1, true),
               query(ar, br, ac, bc, lr, rr, mc, rc, kr, kc * 2 + 2, true));
  }
}

uint naive(int ar, int br, int ac, int bc) {
  uint ans = INF;
  REP2(i, ar, br) REP2(j, ac, bc) ans = min(ans, FIELD(i, j));
  return ans;
}

int main() {
  int r1, r2, c1, c2;
  while (scanf("%d%d%d", &R, &C, &Q) != EOF) {

    REP(r, R) REP(c, C) scanf("%d", &FIELD(r, c));
    if (R > 0 && C > 0)
      build(0, R, 0, C, 0, 0);
    REP(q, Q) {
      scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
      printf("%u\\n", query(r1, r2 + 1, c1, c2 + 1));
    }

#ifdef DEBUG
    REP(r2, R) REP(r1, r2 + 1) REP(c2, C) REP(c1, c2 + 1) {
      // cout << naive(r1, r2 + 1, c1, c2 + 1) << " " << query(r1, r2 + 1, c1,
      // c2 + 1) << endl;
      assert(naive(r1, r2 + 1, c1, c2 + 1) == query(r1, r2 + 1, c1, c2 + 1));
    }
#endif
  }
  return 0;
}