Problem p00653 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <bits/stdc++.h>

using namespace std;

#define INF ((1LL << 31) - 1)
#define D 6

struct SegTree {
  int segSize, realSegSize, nodeSize;
  vector<int> seg;

  void init(int n) {
    realSegSize = n;

    nodeSize = 0;
    for (segSize = 1; segSize < n; segSize *= D)
      nodeSize += segSize;

    seg = vector<int>(nodeSize + n, INF);
  }

  int get(int n) {
    if (n < (int)seg.size())
      return seg[n];
    else
      return INF;
  }
  void set(int n, int v) {
    if (n < (int)seg.size())
      seg[n] = v;
  }

  void update(int pos, int val) {
    int n = nodeSize + pos;
    set(n, val);
    while (n) {
      n = (n - 1) / D;

      int r = INF;
      for (int i = 0; i < D; ++i) {
        r = min(r, seg[n * D + i + 1]);
      }
      set(n, r);
    }
  }
  int get(int n, int l, int r, int L, int R) {
    //		cout << n << " " << l << " " << r << endl;
    if (L <= l && r <= R)
      return get(n);
    else if (R <= l || r <= L)
      return INF;
    else {
      int ret = INF;
      int prev = l;
      for (int i = 0; i < D; ++i) {
        int next = i == D - 1 ? r : prev + (r - l) / D;
        ret = min(ret, get(n * D + i + 1, prev, next, L, R));
        prev = next;
      }
      return ret;
    }
  }
  int get(int L, int R) { return get(0, 0, segSize, L, R); }
};

struct Query {
  int y1, x1, y2, x2;
};

int main() {
  int H, W, Q;
  while (cin >> H >> W >> Q, H || W || Q) {
    vector<vector<int>> m(H, vector<int>(W, 0));

    for (int y = 0; y < H; ++y) {
      for (int x = 0; x < W; ++x) {
        cin >> m[y][x];
      }
    }

    bool isSegRow = H < W;
    vector<SegTree> seg;

    if (isSegRow) {
      seg.resize(H);
      for (int y = 0; y < H; ++y) {
        seg[y].init(W);
      }
    } else {
      seg.resize(W);
      for (int x = 0; x < W; ++x) {
        seg[x].init(H);
      }
    }

    for (int y = 0; y < H; ++y) {
      for (int x = 0; x < W; ++x) {
        if (isSegRow)
          seg[y].update(x, m[y][x]);
        else
          seg[x].update(y, m[y][x]);
      }
    }

    for (int t = 0; t < Q; ++t) {
      int y1, x1, y2, x2;
      cin >> y1 >> x1 >> y2 >> x2;

      int ans = INF;
      if (isSegRow) {
        for (int y = y1; y <= y2; ++y) {
          ans = min(ans, seg[y].get(x1, x2 + 1));
        }
      } else {
        for (int x = x1; x <= x2; ++x) {
          ans = min(ans, seg[x].get(y1, y2 + 1));
        }
      }
      cout << ans << endl;
    }
  }
}

Fixed submission:
#include <bits/stdc++.h>

using namespace std;

#define INF ((1LL << 31) - 1)
#define D 16

struct SegTree {
  int segSize, realSegSize, nodeSize;
  vector<int> seg;

  void init(int n) {
    realSegSize = n;

    nodeSize = 0;
    for (segSize = 1; segSize < n; segSize *= D)
      nodeSize += segSize;

    seg = vector<int>(nodeSize + n, INF);
  }

  int get(int n) {
    if (n < (int)seg.size())
      return seg[n];
    else
      return INF;
  }
  void set(int n, int v) {
    if (n < (int)seg.size())
      seg[n] = v;
  }

  void update(int pos, int val) {
    int n = nodeSize + pos;
    set(n, val);
    while (n) {
      n = (n - 1) / D;

      int r = INF;
      for (int i = 0; i < D; ++i) {
        r = min(r, seg[n * D + i + 1]);
      }
      set(n, r);
    }
  }
  int get(int n, int l, int r, int L, int R) {
    //		cout << n << " " << l << " " << r << endl;
    if (L <= l && r <= R)
      return get(n);
    else if (R <= l || r <= L)
      return INF;
    else {
      int ret = INF;
      int prev = l;
      for (int i = 0; i < D; ++i) {
        int next = i == D - 1 ? r : prev + (r - l) / D;
        ret = min(ret, get(n * D + i + 1, prev, next, L, R));
        prev = next;
      }
      return ret;
    }
  }
  int get(int L, int R) { return get(0, 0, segSize, L, R); }
};

struct Query {
  int y1, x1, y2, x2;
};

int main() {
  int H, W, Q;
  while (cin >> H >> W >> Q, H || W || Q) {
    vector<vector<int>> m(H, vector<int>(W, 0));

    for (int y = 0; y < H; ++y) {
      for (int x = 0; x < W; ++x) {
        cin >> m[y][x];
      }
    }

    bool isSegRow = H < W;
    vector<SegTree> seg;

    if (isSegRow) {
      seg.resize(H);
      for (int y = 0; y < H; ++y) {
        seg[y].init(W);
      }
    } else {
      seg.resize(W);
      for (int x = 0; x < W; ++x) {
        seg[x].init(H);
      }
    }

    for (int y = 0; y < H; ++y) {
      for (int x = 0; x < W; ++x) {
        if (isSegRow)
          seg[y].update(x, m[y][x]);
        else
          seg[x].update(y, m[y][x]);
      }
    }

    for (int t = 0; t < Q; ++t) {
      int y1, x1, y2, x2;
      cin >> y1 >> x1 >> y2 >> x2;

      int ans = INF;
      if (isSegRow) {
        for (int y = y1; y <= y2; ++y) {
          ans = min(ans, seg[y].get(x1, x2 + 1));
        }
      } else {
        for (int x = x1; x <= x2; ++x) {
          ans = min(ans, seg[x].get(y1, y2 + 1));
        }
      }
      cout << ans << endl;
    }
  }
}