Problem p00653 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>

using namespace std;

typedef int ll;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<int> VI;
typedef vector<ll> VL;
typedef pair<int, int> ipair;
typedef tuple<int, int, int> ituple;

// const int MOD = (int)1e9 + 7;
// const double EPS = 1e-10;
#define PI acosl(-1)
#define MAX_N 8000005
ll h, w, H, W, q;
ll dat[MAX_N];

class SegmentTree2D {
protected:
  // ??¨????????????????????????????????¢??°
  virtual ll _func(ll a, ll b) = 0;

  ll query_h(int li, int lj, int ri, int rj, int si, int ti, int k) {
    if (ri <= si or ti <= li)
      return _getDefaultValue();
    if (li <= si and ti <= ri)
      return query_w(lj, rj, 0, W, k, 0);
    const int mi = (si + ti) / 2;
    return _func(query_h(li, lj, ri, rj, si, mi, 2 * k + 1),
                 query_h(li, lj, ri, rj, mi, ti, 2 * k + 2));
  }
  ll query_w(int lj, int rj, int sj, int tj, int i, int k) {
    if (rj <= sj or tj <= lj)
      return _getDefaultValue();
    if (lj <= sj and tj <= rj)
      return get(i, k);
    const int mj = (sj + tj) / 2;
    return _func(query_w(lj, rj, sj, mj, i, 2 * k + 1),
                 query_w(lj, rj, mj, tj, i, 2 * k + 2));
  }

public:
  // ??¨???????????????????????????????????????????????????????????????
  virtual ll _getDefaultValue() = 0;

  SegmentTree2D() {}

  ll get(int hh, int ww) {
    // printf("get (%d, %d)[%lld] = %lld\n", hh, ww, hh*W+ww, dat[hh * W + ww]);
    return dat[hh * 2 * W + ww];
  }

  void set(int hh, int ww, ll v) {
    // printf("set (%d, %d)[%lld] = %lld\n", hh, ww, hh*W+ww, v);
    dat[hh * 2 * W + ww] = v;
  }

  void init() {
    // H = W = 1;
    // while(H < (int)f.size()) H <<= 1;
    // while(W < (int)f[0].size()) W <<= 1;
    // dat.assign(2*H-1,VL(2*W-1, _getDefaultValue()));
    for (int i = 2 * H - 2; i > H - 2; i--)
      for (int j = W - 2; j >= 0; j--) {
        set(i, j, _func(get(i, 2 * j + 1), get(i, 2 * j + 2)));
      }
    for (int i = H - 2; i >= 0; i--)
      for (int j = 0; j < 2 * W - 1; j++) {
        set(i, j, _func(get(2 * i + 1, j), get(2 * i + 2, j)));
      }
  }
  // [(li, ri), (lj, rj)]??????????????¨???????±???????
  ll query(int li, int lj, int ri, int rj) {
    return query_h(li, lj, ri + 1, rj + 1, 0, H, 0);
  }
};

class SegmentTree2DMin : public SegmentTree2D {
  using SegmentTree2D::SegmentTree2D;

protected:
  // ??¨????????????????????????????????¢??°
  ll _func(ll a, ll b) { return min(a, b); }

public:
  // ??¨???????????????????????????????????????????????????????????????
  ll _getDefaultValue() { return INT_MAX; }
};

void exec() {

  int tmp, r1, r2, c1, c2;
  SegmentTree2DMin st2 = SegmentTree2DMin();
  for (int i = 0; i < MAX_N; i++) {
    dat[i] = st2._getDefaultValue();
  }
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++) {
      scanf("%d", &tmp);
      st2.set(i + H - 1, j + W - 1, tmp);
    }
  st2.init();

  for (int i = 0; i < q; i++) {
    scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
    printf("%d\n", st2.query(r1, c1, r2, c2));
  }
}

void solve() {
  while (scanf("%d%d%d", &h, &w, &q) != EOF) {
    if (h + w + q <= 0) {
      break;
    }
    H = W = 1;
    while (H < h)
      H <<= 1;
    while (W < w)
      W <<= 1;
    exec();
  }
}

int main() {
  solve();
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>

using namespace std;

typedef int ll;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<int> VI;
typedef vector<ll> VL;
typedef pair<int, int> ipair;
typedef tuple<int, int, int> ituple;

// const int MOD = (int)1e9 + 7;
// const double EPS = 1e-10;
#define PI acosl(-1)
#define MAX_N 9000005
ll h, w, H, W, q;
ll dat[MAX_N];

class SegmentTree2D {
protected:
  // ??¨????????????????????????????????¢??°
  virtual ll _func(ll a, ll b) = 0;

  ll query_h(int li, int lj, int ri, int rj, int si, int ti, int k) {
    if (ri <= si or ti <= li)
      return _getDefaultValue();
    if (li <= si and ti <= ri)
      return query_w(lj, rj, 0, W, k, 0);
    const int mi = (si + ti) / 2;
    return _func(query_h(li, lj, ri, rj, si, mi, 2 * k + 1),
                 query_h(li, lj, ri, rj, mi, ti, 2 * k + 2));
  }
  ll query_w(int lj, int rj, int sj, int tj, int i, int k) {
    if (rj <= sj or tj <= lj)
      return _getDefaultValue();
    if (lj <= sj and tj <= rj)
      return get(i, k);
    const int mj = (sj + tj) / 2;
    return _func(query_w(lj, rj, sj, mj, i, 2 * k + 1),
                 query_w(lj, rj, mj, tj, i, 2 * k + 2));
  }

public:
  // ??¨???????????????????????????????????????????????????????????????
  virtual ll _getDefaultValue() = 0;

  SegmentTree2D() {}

  ll get(int hh, int ww) {
    // printf("get (%d, %d)[%lld] = %lld\n", hh, ww, hh*W+ww, dat[hh * W + ww]);
    return dat[hh * 2 * W + ww];
  }

  void set(int hh, int ww, ll v) {
    // printf("set (%d, %d)[%lld] = %lld\n", hh, ww, hh*W+ww, v);
    dat[hh * 2 * W + ww] = v;
  }

  void init() {
    // H = W = 1;
    // while(H < (int)f.size()) H <<= 1;
    // while(W < (int)f[0].size()) W <<= 1;
    // dat.assign(2*H-1,VL(2*W-1, _getDefaultValue()));
    for (int i = 2 * H - 2; i > H - 2; i--)
      for (int j = W - 2; j >= 0; j--) {
        set(i, j, _func(get(i, 2 * j + 1), get(i, 2 * j + 2)));
      }
    for (int i = H - 2; i >= 0; i--)
      for (int j = 0; j < 2 * W - 1; j++) {
        set(i, j, _func(get(2 * i + 1, j), get(2 * i + 2, j)));
      }
  }
  // [(li, ri), (lj, rj)]??????????????¨???????±???????
  ll query(int li, int lj, int ri, int rj) {
    return query_h(li, lj, ri + 1, rj + 1, 0, H, 0);
  }
};

class SegmentTree2DMin : public SegmentTree2D {
  using SegmentTree2D::SegmentTree2D;

protected:
  // ??¨????????????????????????????????¢??°
  ll _func(ll a, ll b) { return min(a, b); }

public:
  // ??¨???????????????????????????????????????????????????????????????
  ll _getDefaultValue() { return INT_MAX; }
};

void exec() {

  int tmp, r1, r2, c1, c2;
  SegmentTree2DMin st2 = SegmentTree2DMin();
  for (int i = 0; i < MAX_N; i++) {
    dat[i] = st2._getDefaultValue();
  }
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++) {
      scanf("%d", &tmp);
      st2.set(i + H - 1, j + W - 1, tmp);
    }
  st2.init();

  for (int i = 0; i < q; i++) {
    scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
    printf("%d\n", st2.query(r1, c1, r2, c2));
  }
}

void solve() {
  while (scanf("%d%d%d", &h, &w, &q) != EOF) {
    if (h + w + q <= 0) {
      break;
    }
    H = W = 1;
    while (H < h)
      H <<= 1;
    while (W < w)
      W <<= 1;
    exec();
  }
}

int main() {
  solve();
  return 0;
}