Competitive Programming

18. 구간 쿼리, 구간 합 (Range queries, Prefix sum, c++)

소파와 바보개 2025. 3. 19. 23:30
728x90

구간 쿼리 (Range queries)?

구간에 대한 쿼리에서는 배열의 부분 배열들을 기반으로 어떠한 값들을 계산합니다.

 

예를 들면 [a, b] 구간의 합계를 구한다던지, [a, b] 구간에서의 최솟값을 구하는 경우들이 있고, 이러한 종류의 연산들을 효과적으로 처리할 수 있는 자료구조들이 있습니다.


Prefix Sum

구간에 대한 합계를 구하는 연산은 미리 계산된 prefix sum array를 통해 쉽계 계산할 수 있습니다.

 

prefix sum array의 각각의 요소들은 원본 배열에서의 해당 위치까지의 합계입니다.

 

따라서, prefix sum array를 만드는 과정은 단순히 이전까지의 값에 현재 값을 더하는 것으로  O(N)에 수행됩니다.

 

예를 들어 { 1, 3, 4, 8, 6, 1, 4, 2 } 라는 원본 배열이 있다면

 

prefix sum array 는 { 1, 4, 8, 16, 22, 23, 27, 29 } 와 같이 계산할 수 있습니다.

 

이 때, 0번째부터 k번째 까지의 구간합인 sum(0, k) 는 prefix sum array를 조회함으로써 O(1) 시간복잡도로 계산할 수 있게됩니다.

 

그러므로 a번째부터 b번째 까지의 구간합인 sum(a, b)는 sum(0,b)-sum(0,a-1) 로 구할 수 있으며 마찬가지로 O(1) 시간복잡도로 계산이 됩니다.

 

위 배열을 예로 들면 3~6 번쨰 구간 {4, 8, 6, 1}의 합은 psum[6]-psum[2] = 23-4=19 로 계산할 수 있습니다.


2D Prefix Sum

같은 방식으로 2차원 배열에 대한 prefix sum array를 계산하는 것으로 2차원 배열에서의 사각형 범위의 합을 O(1)의 시간복잡도로 계산할 수 있습니다.

 

아래와 같은 2차원 배열이 각각의 숫자를 가지고 있고 초록색 사각형 범위에 대한 구간 합을 구하려고 합니다.

 

psum[X]는 왼쪽 최상단에서 부터 X 까지의 사각형 구간의 합이라고 정의합니다.

 

계산된 값을 이용하여 초록색 사각형 범위의 합계는 A까지의 총 합계에서 B와 C 까지의 사각형 합계를 빼고 중복된 구간인 D까지의 합계를 더하는 것으로 계산할 수 있습니다.

 

따라서 psum[A]-psum[B]-psum[C]+psum[D] 로 O(1)에 계산할 수 있습니다.

 

 

 

728x90