풀이


dp 라는 2차원 배열에 각 좌표의 합을 넣어준 뒤,

dp[x][y] - dp[x][j-1] - dp[i-1][y] + dp[i-1][j-1] 라는 식을 통해 범위가 주어졌을때의 값을 반환하면된다.

예를 들어,

arr 가 아래 처럼 주어졌을때

0000
0124
081632

dp 는 아래와 같다.

0000
0137
092763

i, j, x, y = 2, 2, 2, 3 일때를 예로 들어보자.

arr[2][2] 부터 arr[2][3] 까지의 합은 16 + 32 = 48 이다.

위에 설명된 식을 통해 확인해보면

dp[2][3] - dp[2][1] - dp[1][3] + dp[1][1] = 63 - 9 - 7 + 1 = 36 으로 값이 같다는 것을 확인할 수 있다.

위 예에서 구하고자했던 값은 arr[2][2] 부터 arr[2][3] 까지의 합은

arr[0][0] 부터 arr[2][3] 까지의 합 - arr[0][0] 부터 arr[2][1] 까지의 합 - arr[0][0] 부터 arr[1][3] 까지의 합 + 겹치는 부분인 arr[0][0] 부터 arr[1][1] 까지의 합 인 것이다.

위 설명을 dp에서 표현했을 경우 dp[2][3] - dp[2][1] - dp[1][3] + dp[1][1] 와 같은 식이 된다는 것을 알 수 있을 것이다.

소스코드


import sys
input = sys.stdin.readline
 
N, M = map(int, input().split())
arr = [list(map(int, input().split())) for _ in range(N)]
dp = [[0]*(M+1) for _ in range(N+1)]
 
for i in range(1, N+1):
    for j in range(1, M+1):
        dp[i][j] = arr[i-1][j-1] + dp[i][j-1] + dp[i-1][j] - dp[i-1][j-1]
 
K = int(input())
 
for _ in range(K):
    i, j, x, y = map(int, input().split())
    print(dp[x][y] - dp[x][j-1] - dp[i-1][y] + dp[i-1][j-1])

References