Language: C++

#include<bits/stdc++.h>
using namespace std;

// library
#include<vector>
#include<climitts>
#include<algorithm>
// constant
const int INF = INT_MAX;
// class
class SegmentTree {
public:
  SegmentTree(int x, int y);
  void update(int x, int y, int value);
  int find(int x1, int y1, int x2, int y2) const;
  void print();
private:
  void update(int index, int a1, int b1, int a2, int b2, int x, int y, int value);
  int find(int index, int a1, int b1, int a2, int b2, int x1, int y1, int x2, int y2) const;
  int parent(int index) const;
  int upper_left(int index) const;
  int upper_right(int index) const;
  int lower_left(int index) const;
  int lower_right(int index) const;
  std::vector<int> node_;
  int height_;
  int width_;
  int size_;
};
// constructor
SegmentTree::SegmentTree(int x, int y) : width_(x), height_(y) {
  size_ = 1;
  for(int i = 1; i < std::max(x, y); i <<= 1) size_ <<= 2;
  node_.assign(size_, INF);
}
// set value on (x, y)
void SegmentTree::update(int x, int y, int value) {
  update(0, 0, 0, width_ - 1, height_ - 1, x, y, value);
}
void SegmentTree::update(int index, int a1, int b1, int a2, int b2, int x, int y, int value) {
  if(size_ <= index) return;
  if(x < a1 || a2 < x) return;
  if(y < b1 || b2 < y) return;
  if(a1 == x && x == a2 && b1 == y && y == b2) {
    node_[index] = value;
    while(index) {
      node_[parent(index)] = std::min(node_[parent(index)], node_[index]);
      index = parent(index);
    }
  } else {
    int a = (a1 + a2) >> 1;
    int b = (b1 + b2) >> 1;
    update(upper_left(index), a1, b1, a, b, x, y, value);
    update(upper_right(index), a + 1, b1, a2, b, x, y, value);
    update(lower_left(index), a1, b + 1, a, b2, x, y, value);
    update(lower_right(index), a + 1, b + 1, a2, b2, x, y, value);
  }
}
// find the minimum value in (x1, y1)-(x2, y2)
int SegmentTree::find(int x1, int y1, int x2, int y2) const {
  return find(0, 0, 0, width_ - 1, height_ - 1, x1, y1, x2, y2);
}
int SegmentTree::find(int index, int a1, int b1, int a2, int b2, int x1, int y1, int x2, int y2) const {
//   for(int i=0;i<(index-1)>>2;++i)cout<<" ";
//   cout<<"*"<<index<<"* "<<a1<<" "<<b1<<" "<<a2<<" "<<b2<<endl;
  if(size_ <= index) return INF;
  if(x2 < a1 || a2 < x1) return INF;
  if(y2 < b1 || b2 < y1) return INF;
  if(x1 <= a1 && a2 <= x2 && y1 <= b1 && b2 <= y2) return node_[index];
  int a = (a1 + a2) >> 1;
  int b = (b1 + b2) >> 1;
  int ul = find(upper_left(index), a1, b1, a, b, x1, y1, x2, y2);
  int ur = find(upper_right(index), a + 1, b1, a2, b, x1, y1, x2, y2);
  int ll = find(lower_left(index), a1, b + 1, a, b2, x1, y1, x2, y2);
  int lr = find(lower_right(index), a + 1, b + 1, a2, b2, x1, y1, x2, y2);
  return std::min({ul, ur, ll, lr});
}
// debug
void SegmentTree::print() {
  for(auto i: node_) cout<<" "<<i;cout<<endl;
}
// position
int SegmentTree::parent(int index) const {return (index - 1) >> 2;}
int SegmentTree::upper_left(int index) const {return (index << 2) + 1;}
int SegmentTree::upper_right(int index) const {return (index << 2) + 2;}
int SegmentTree::lower_left(int index) const {return (index << 2) + 3;}
int SegmentTree::lower_right(int index) const {return (index << 2) + 4;}

#include<bits/stdc++.h>
using namespace std;
int main() {
  int r, c, q;
  while(cin >> r >> c >> q, r | c | q) {
    SegmentTree tree(c, r);
    for(int y = 0; y < r; ++y) for(int x = 0; x < c; ++x) {
      int grid;
      cin >> grid;
      tree.update(x, y, grid);
    }
//     tree.print();
    for(int i = 0; i < q; ++i) {
      int r1, c1, r2, c2;
      cin >> r1 >> c1 >> r2 >> c2;
      cout << tree.find(c1, r1, c2, r2) << endl;
    }
  }
}

Compiler output:
a.cc:6:9: fatal error: climitts: No such file or directory
    6 | #include<climitts>
      |         ^~~~~~~~~~
compilation terminated.