/*
* Problem :: 16507 / 어두운 건 무서워
*
* Kind :: Math
*
* Insight
* - (r1,c1)=(1,1) 그리고 (r2,c2)=(N,N) 이며
* max(Q)=10000 번 주어진다고 했을 때,
* 각 쿼리마다 매번 포함된 칸을 하나씩 센다면 시간초과가 날 수밖에 없다
* + 밝기의 합을 저장해놓고 사용할 수는 없을까? <= Dynamic Programming
* 누적합을 이용하자!
* # dp[i][j] = (1,1)~(i,j) 칸의 합
* -> (r1,c1)~(r2,c2) 칸의 합은 위를 이용해서
* dp[r2][c2] - dp[r1-1][c2] - dp[r2][c1-1] + dp[r1][c1] 으로 구할 수 있다!
* Point
* - (r1,c1)=(1,1) 인 경우
* dp[r1-1][c2] = dp[0][c2]
* dp[r2][c1-1] = dp[r2][0]
* dp[r1][c1] = dp[0][0] 이 된다
* + 문제에서는 좌표가 0 이 될 수 없지만 위와같은 예외를 처리하기 위해
* 코드에서는 y좌표나 x좌표가 0 이 될 수 있으며 각 칸의 값은 0 으로 간주하자
* # 따라서, (i,j) 에서 i 나 j 가 0 이면 dp[i][j] = 0 이다
* -> dp[i][j] = (0,0)~(i,j) 칸의 합
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <cstring>
using namespace std;
#define endl '\n'
// Set up : Global Variables
/* None */
// Set up : Functions Declaration
/* None */
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int R, C, Q;
cin >> R >> C >> Q;
int P[R+1][C+1];
memset(P, 0, sizeof(P));
for (int i=1; i<=R; i++) {
for (int j=1; j<=C; j++) {
cin >> P[i][j];
}
}
// Process
int dp[R+1][C+1]; /* dp[i][j] = (0,0)~(i,j) 칸의 합 */
memset(dp, 0, sizeof(dp)); /* (0,0)~(0,C) 와 (0,0)~(R,0) 칸의 밝기는 0 */
for (int i=1; i<=R; i++) {
for (int j=1; j<=C; j++) {
/* (0,0)~(i,j) 칸의 합
* =
* (i,j) 칸의 값
* +
* (0,0)~(i,j-1) 칸의 합
* +
* (0,0)~(i-1,j) 칸의 합
* -
* (0.0)~(i-1,j-1) 칸의 합 */
dp[i][j] = P[i][j] + dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1];
}
}
// Control : Output
for (int i=0; i<Q; i++) {
int r1, c1, r2, c2;
cin >> r1 >> c1 >> r2 >> c2;
int size = (r2-r1+1)*(c2-c1+1); /* 칸의 개수 */
/* (r1,c1)~(r2,c2) 칸의 합
* =
* (0,0)~(r2,c2) 칸의 합
* -
* (0,0)~(r2,c1-1) 칸의 합
* -
* (0,0)~(r1-1,c2) 칸의 합
* +
* (0,0)~(r1-1,c1-1) 칸의 합 */
int sum = dp[r2][c2] - dp[r1-1][c2] - dp[r2][c1-1] + dp[r1-1][c1-1];
cout << sum / size << endl;
}
}
// Helper Functions
/* None */