Problem p00653 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int INF = (1LL << 31) - 1;

struct segtree {
  int H, W, H_, W_;
  int dat[4000000];
  segtree() {}
  segtree(vector<vector<int>> &f) { init(f); }
  int x(int i, int j) { return i * W_ + j; }

  void init(vector<vector<int>> &f) {
    H = W = 1;
    while (H < (int)f.size())
      H <<= 1;
    while (W < (int)f[0].size())
      W <<= 1;
    H_ = 2 * H - 1, W_ = 2 * W - 1;
    for (int i = 0; i < (int)f.size(); i++)
      for (int j = 0; j < (int)f[0].size(); j++)
        dat[x(i + H - 1, j + W - 1)] = f[i][j];
    for (int i = 2 * H - 2; i > H - 2; i--)
      for (int j = W - 2; j >= 0; j--)
        dat[x(i, j)] = min(dat[x(i, 2 * j + 1)], dat[x(i, 2 * j + 2)]);
    for (int i = H - 2; i >= 0; i--)
      for (int j = 0; j < 2 * W - 1; j++)
        dat[x(i, j)] = min(dat[x(2 * i + 1, j)], dat[x(2 * i + 2, j)]);
  }
  int query(int li, int lj, int ri, int rj) {
    return query_h(li, lj, ri, rj, 0, H, 0);
  }
  int query_h(int li, int lj, int ri, int rj, int si, int ti, int k) {
    if (ri <= si || ti <= li)
      return INF;
    if (li <= si && ti <= ri)
      return query_w(lj, rj, 0, W, k, 0);
    const int mi = (si + ti) / 2;
    return min(query_h(li, lj, ri, rj, si, mi, 2 * k + 1),
               query_h(li, lj, ri, rj, mi, ti, 2 * k + 2));
  }
  int query_w(int lj, int rj, int sj, int tj, int i, int k) {
    if (rj <= sj || tj <= lj)
      return INF;
    if (lj <= sj && tj <= rj)
      return dat[x(i, k)];
    const int mj = (sj + tj) / 2;
    return min(query_w(lj, rj, sj, mj, i, 2 * k + 1),
               query_w(lj, rj, mj, tj, i, 2 * k + 2));
  }
};

vector<vector<int>> f;
segtree st;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int r, c, q;
  while (cin >> r >> c >> q, r | c | q) {
    f.assign(r, vector<int>(c, 0));
    for (int i = 0; i < r; i++) {
      for (int j = 0; j < c; j++) {
        cin >> f[i][j];
      }
    }

    st.init(f);
    while (q--) {
      int r1, c1, r2, c2;
      cin >> r1 >> c1 >> r2 >> c2;
      cout << st.query(r1, c1, r2 + 1, c2 + 1) << endl;
    }
  }
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int INF = (1LL << 31) - 1;

struct segtree {
  int H, W, H_, W_;
  int dat[9000000];
  segtree() {}
  segtree(vector<vector<int>> &f) { init(f); }
  int x(int i, int j) { return i * W_ + j; }

  void init(vector<vector<int>> &f) {
    H = W = 1;
    while (H < (int)f.size())
      H <<= 1;
    while (W < (int)f[0].size())
      W <<= 1;
    H_ = 2 * H - 1, W_ = 2 * W - 1;
    for (int i = 0; i < (int)f.size(); i++)
      for (int j = 0; j < (int)f[0].size(); j++)
        dat[x(i + H - 1, j + W - 1)] = f[i][j];
    for (int i = 2 * H - 2; i > H - 2; i--)
      for (int j = W - 2; j >= 0; j--)
        dat[x(i, j)] = min(dat[x(i, 2 * j + 1)], dat[x(i, 2 * j + 2)]);
    for (int i = H - 2; i >= 0; i--)
      for (int j = 0; j < 2 * W - 1; j++)
        dat[x(i, j)] = min(dat[x(2 * i + 1, j)], dat[x(2 * i + 2, j)]);
  }
  int query(int li, int lj, int ri, int rj) {
    return query_h(li, lj, ri, rj, 0, H, 0);
  }
  int query_h(int li, int lj, int ri, int rj, int si, int ti, int k) {
    if (ri <= si || ti <= li)
      return INF;
    if (li <= si && ti <= ri)
      return query_w(lj, rj, 0, W, k, 0);
    const int mi = (si + ti) / 2;
    return min(query_h(li, lj, ri, rj, si, mi, 2 * k + 1),
               query_h(li, lj, ri, rj, mi, ti, 2 * k + 2));
  }
  int query_w(int lj, int rj, int sj, int tj, int i, int k) {
    if (rj <= sj || tj <= lj)
      return INF;
    if (lj <= sj && tj <= rj)
      return dat[x(i, k)];
    const int mj = (sj + tj) / 2;
    return min(query_w(lj, rj, sj, mj, i, 2 * k + 1),
               query_w(lj, rj, mj, tj, i, 2 * k + 2));
  }
};

vector<vector<int>> f;
segtree st;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int r, c, q;
  while (cin >> r >> c >> q, r | c | q) {
    f.assign(r, vector<int>(c, 0));
    for (int i = 0; i < r; i++) {
      for (int j = 0; j < c; j++) {
        cin >> f[i][j];
      }
    }

    st.init(f);
    while (q--) {
      int r1, c1, r2, c2;
      cin >> r1 >> c1 >> r2 >> c2;
      cout << st.query(r1, c1, r2 + 1, c2 + 1) << endl;
    }
  }
}