[백준/코틀린] 11660번: 구간 합 구하기 5
실버 1
링크
풀이
테이블의 모든 위치까지의 누적 합을 미리 계산해
2차원 누적 합(prefix sum) 테이블을 만들어두면,
구간 [(y1, x1) ~ (y2, x2)]의 합을 O(1)에 구할 수 있습니다.
2차원 누적 합 테이블
출처: Wikipedia: Summed-area table
생성
누적 합 테이블을 생성할 때,
(i, j)위치의 누적 합 prefixSum[i][j]은 다음과 같이 계산됩니다.
nums[i][j]: 해당 위치의 값prefixSum[i - 1][j]: 위쪽 영역의 누적 합prefixSum[i][j - 1]: 왼쪽 영역의 누적 합prefixSum[i - 1][j - 1]: 겹치는 부분(왼쪽 위)의 누적 합
계산
예를 들어, 위와 같이 누적 합 테이블을 미리 계산해 두었다면,
구간 [(4, 3) ~ (5, 5)]의 합은 다음처럼 구할 수 있습니다.
prefixSum[3][2]: 겹치는 영역 = 28prefixSum[5][5]: 전체 영역 = 110prefixSum[3][5]: 위쪽 제외 = 65prefixSum[5][2]: 왼쪽 제외 = 46
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
fun main() {
val (n, m) = readln().split(" ").map { it.toInt() }
val nums = List(n) { readln().split(" ").map { it.toInt() } }
val prefixSum = Array(n + 1) { IntArray(n + 1) }
for (i in 1..n) {
for (j in 1..n) {
prefixSum[i][j] = nums[i - 1][j - 1] + prefixSum[i - 1][j] + prefixSum[i][j - 1] - prefixSum[i - 1][j - 1]
}
}
repeat(m) {
val (x1, y1, x2, y2) = readln().split(" ").map { it.toInt() }
println(prefixSum[x2][y2] - prefixSum[x2][y1 - 1] - prefixSum[x1 - 1][y2] + prefixSum[x1 - 1][y1 - 1])
}
}
연관 문제
- [백준/코틀린] 11659번: 구간 합 구하기 4 - 1차원 누적합
This post is licensed under CC BY 4.0 by the author.