Language: C++

#include <cstdio>
#include <iostream>
#include <vector>
#define N 2555555

using namespace std;

struct node {
	int lx, ly, rx, ry, mx, my, f;
} tree[N * 100];

vector<int> a[N];

void build(int d, int lx, int ly, int rx, int ry) {
	tree[d].lx = lx;
	tree[d].rx = rx;
	tree[d].ly = ly;
	tree[d].ry = ry;
	if (lx == rx && ly == ry) {
		tree[d].f = a[lx][ly];
		return;
	}
	tree[d].mx = (lx + rx) >> 1;
	tree[d].my = (ly + ry) >> 1;
	if (lx == rx) {
		build(d << 2, lx, ly, lx, tree[d].my);
		build(d << 2 | 1, lx, tree[d].my + 1, rx, ry);
		tree[d].f = min(tree[d << 2].f, tree[d << 2 | 1].f);
	} else if (ly == ry) {
		build(d << 2 | 2, lx, ly, tree[d].mx, ry);
		build(d << 2 | 3, tree[d].mx + 1, ry, rx, ry);
		tree[d].f = min(tree[d << 2 | 2].f, tree[d << 2 | 3].f);
	} else {
		build(d << 2, lx, ly, tree[d].mx, tree[d].my);
		build(d << 2 | 1, lx, tree[d].my + 1, tree[d].mx, ry);
		build(d << 2 | 2, tree[d].mx + 1, ly, rx, tree[d].my);
		build(d << 2 | 3, tree[d].mx + 1, tree[d].my + 1, rx, ry);
		int ll = min(tree[d << 2].f, tree[d << 2 | 1].f);
		int rr = min(tree[d << 2 | 2].f, tree[d << 2 | 3].f);
		tree[d].f = min(ll, rr);
	}
}

int find(int d, int lx, int ly, int rx, int ry) {
	if (lx == tree[d].lx && ly == tree[d].ly && rx == tree[d].rx && ry == tree[d].ry) return tree[d].f;
	if (rx <= tree[d].mx && ry <= tree[d].my) return find(d << 2, lx, ly, rx, ry);
	if (rx <= tree[d].mx && ly > tree[d].my) return find(d << 2 | 1, lx, ly, rx, ry);
	if (lx > tree[d].mx && ry <= tree[d].my) return find(d << 2 | 2, lx, ly, rx, ry);
	if (lx > tree[d].mx && ly > tree[d].my) return find(d << 2 | 3, lx, ly, rx, ry);
	if (rx <= tree[d].mx) return min(find(d << 2, lx, ly, rx, tree[d].my), find(d << 2 | 1, lx, tree[d].my + 1, rx, ry));
	if (lx > tree[d].mx) return min(find(d << 2 | 2, lx, ly, rx, tree[d].my), find(d << 2 | 3, lx, tree[d].my + 1, rx, ry));
	if (ry <= tree[d].my) return min(find(d << 2, lx, ly, tree[d].mx, ry), find(d << 2 | 2, tree[d].mx + 1, ly, rx, ry));
	if (ry > tree[d].my) return min(find(d << 2 | 1, lx, ly, tree[d].mx, ry), find(d << 2 | 3, tree[d].mx + 1, ly, rx, ry));
	int ll = min(find(d << 2, lx, ly, tree[d].mx, tree[d].my), find(d << 2 | 2, tree[d].mx + 1, ly, rx, tree[d].my));
	int rr = min(find(d << 2 | 1, lx, tree[d].my + 1, tree[d].mx, ry), find(d << 2 | 3, tree[d].mx + 1, tree[d].my + 1, rx, ry));
	return min(ll, rr);
}

int main() {
	int n, m, T;
	scanf("%d%d%d", &n, &m, &T);
	while (m + n + T) {
		for (int i = 1; i <= n; i++) {
			a[i].clear();
			a[i].push_back(0);
			for (int j = 1; j <= m; j++) {
				int x;
				scanf("%d", &x);
				a[i].push_back(x);
			}
		}
		build(1, 1, 1, n, m);
		for (int i = 1; i <= T; i++) {
			int xl, xr, yl, yr;
			scanf("%d%d%d%d", &xl, &yl, &xr, &yr);
			printf("%d\n", find(1, xl + 1, yl + 1, xr + 1, yr + 1));
		}
		scanf("%d%d%d", &n, &m, &T);
	}
	return 0;
}

Compiler output:
/tmp/ccPE1kzA.o: in function `build(int, int, int, int, int)':
a.cc:(.text+0xce): relocation truncated to fit: R_X86_64_PC32 against symbol `a' defined in .bss section in /tmp/ccPE1kzA.o
/tmp/ccPE1kzA.o: in function `main':
a.cc:(.text+0xe24): relocation truncated to fit: R_X86_64_PC32 against symbol `a' defined in .bss section in /tmp/ccPE1kzA.o
a.cc:(.text+0xe49): relocation truncated to fit: R_X86_64_PC32 against symbol `a' defined in .bss section in /tmp/ccPE1kzA.o
a.cc:(.text+0xea0): relocation truncated to fit: R_X86_64_PC32 against symbol `a' defined in .bss section in /tmp/ccPE1kzA.o
/tmp/ccPE1kzA.o: in function `__tcf_0':
a.cc:(.text+0xfbc): relocation truncated to fit: R_X86_64_PC32 against symbol `a' defined in .bss section in /tmp/ccPE1kzA.o
a.cc:(.text+0xfca): relocation truncated to fit: R_X86_64_PC32 against symbol `a' defined in .bss section in /tmp/ccPE1kzA.o
/tmp/ccPE1kzA.o: in function `__static_initialization_and_destruction_0()':
a.cc:(.text+0xff1): relocation truncated to fit: R_X86_64_PC32 against symbol `a' defined in .bss section in /tmp/ccPE1kzA.o
collect2: error: ld returned 1 exit status