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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
#define N 1000000
using namespace std;

int n;
int r, c, q;
int r1, c1, r2, c2;
int grid[N];
vector<int> seg[1000];

void init(int num, int n_) {
  for (int i = 0; i < 2 * n_ - 1; i++)
    seg[num].push_back((1 << 31) - 1);
}

void update(int x, int k, int a) {
  k += n - 1;
  seg[x][k] = a;
  while (k > 0) {
    k = (k - 1) / 2;
    seg[x][k] = min(seg[x][k * 2 + 1], seg[x][k * 2 + 2]);
  }
}

int query(int x, int a, int b, int k, int l, int r) {
  if (r <= a || b <= l)
    return (1 << 31) - 1;
  if (a <= l && r <= b)
    return seg[x][k];
  else {
    return min(query(x, a, b, 2 * k + 1, l, (l + r) / 2),
               query(x, a, b, 2 * k + 2, (l + r) / 2, r));
  }
}

int main() {
  while (1) {
    cin >> r >> c >> q;
    if (!r && !c && !q)
      break;

    for (int i = 0; i < r; i++) {
      for (int j = 0; j < c; j++)
        cin >> grid[i * c + j];
    }

    if (r >= c) {
      n = 1;
      while (n < r)
        n *= 2;
      for (int i = 0; i < c; i++)
        init(i, n);
      for (int i = 0; i < c; i++) {
        for (int j = 0; j < r; j++)
          update(i, j, grid[j * c + i]);
      }
      while (q--) {
        cin >> r1 >> c1 >> r2 >> c2;
        int ans = (1 << 31) - 1;
        for (int i = c1; i <= c2; i++)
          ans = min(ans, query(i, r1, r2 + 1, 0, 0, n));
        cout << ans << endl;
      }
    } else {
      n = 1;
      while (n < c)
        n *= 2;
      for (int i = 0; i < r; i++)
        init(i, n);
      for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++)
          update(i, j, grid[i * c + j]);
      }
      while (q--) {
        cin >> r1 >> c1 >> r2 >> c2;
        int ans = (1 << 31) - 1;
        for (int i = r1; i <= r2; i++)
          ans = min(ans, query(i, c1, c2 + 1, 0, 0, n));
        cout << ans << endl;
      }
    }
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#define N 1000000
using namespace std;

int main() {
  int r, c, q;
  int r1, c1, r2, c2;
  int grid[N];
  int rmq[N];

  while (1) {
    cin >> r >> c >> q;
    if (!r && !c && !q)
      break;

    int bs_r = (int)sqrt(r), bs_c = (int)sqrt(c);
    int bn_r = r / bs_r, bn_c = c / bs_c;
    if (r % bs_r)
      bn_r++;
    if (c % bs_c)
      bn_c++;

    for (int i = 0; i < bn_r; i++) {
      for (int j = 0; j < bn_c; j++)
        rmq[i * bn_c + j] = (1 << 31) - 1;
    }

    for (int i = 0; i < r; i++) {
      for (int j = 0; j < c; j++) {
        cin >> grid[i * c + j];
        if (rmq[(i / bs_r) * bn_c + (j / bs_c)] > grid[i * c + j])
          rmq[(i / bs_r) * bn_c + (j / bs_c)] = grid[i * c + j];
      }
    }

    while (q--) {
      cin >> r1 >> c1 >> r2 >> c2;
      int ans = (1 << 31) - 1;

      int sr = r1 / bs_r;
      int sc = c1 / bs_c;
      int gr = r2 / bs_r;
      int gc = c2 / bs_c;

      if (sr == gr || sc == gc) {
        for (int i = r1; i <= r2; i++) {
          for (int j = c1; j <= c2; j++) {
            if (ans > grid[i * c + j])
              ans = grid[i * c + j];
          }
        }
      } else {
        if (r1 % bs_r) {
          sr++;
          for (int i = r1; i < sr * bs_r; i++) {
            for (int j = c1; j <= c2; j++) {
              if (ans > grid[i * c + j])
                ans = grid[i * c + j];
            }
          }
        }

        if (c1 % bs_c) {
          sc++;
          for (int i = r1; i <= r2; i++) {
            for (int j = c1; j < sc * bs_c; j++) {
              if (ans > grid[i * c + j])
                ans = grid[i * c + j];
            }
          }
        }

        if ((r2 + 1) % bs_r) {
          for (int i = gr * bs_r; i <= r2; i++) {
            for (int j = c1; j <= c2; j++) {
              if (ans > grid[i * c + j])
                ans = grid[i * c + j];
            }
          }
          gr--;
        }

        if ((c2 + 1) % bs_c) {
          for (int i = r1; i <= r2; i++) {
            for (int j = gc * bs_c; j <= c2; j++) {
              if (ans > grid[i * c + j])
                ans = grid[i * c + j];
            }
          }
          gc--;
        }

        for (int i = sr; i <= gr; i++) {
          for (int j = sc; j <= gc; j++) {
            if (ans > rmq[i * bn_c + j])
              ans = rmq[i * bn_c + j];
          }
        }
      }

      cout << ans << endl;
    }
  }
}