[알고리즘] 구간 합

yeonjuLee·2025년 4월 25일

코딩테스트 대비

목록 보기
25/32
post-thumbnail

1차원 구간 합 (Immutable)

누적 합 SS 정의

S[0]=0S[0] = 0
S[i+1]=S[i]+A[i](0i<N)S[i+1] = S[i] + A[i] \quad (0 \leq i < N)

구간 합 A[L,R]A[L, R] 정의

k=LRA[k]=S[R+1]S[L]\sum_{k=L}^{R} A[k] = S[R+1] - S[L]
  • S[0]=0S[0] = 0 으로 두면, LL00일 때 음수 인덱스 방지할 수 있어 인덱스 관리가 편함.

  • 합뿐만 아니라 곱셈이나 XOR 연산도 유사하게 동작할 수 있습니다. 하지만 곱셈의 경우 값이 커지므로 모듈러 연산이 필요합니다.

    k=LRA[k]=S[R+1]S[L]\prod_{k=L}^{R} A[k] = \frac{S[R+1]}{S[L]}
#include <bits/stdc++.h>
using namespace std;

int main() {
    int N, M; cin >> N >> M;
    vector<int> prefixSum(N + 1, 0);
    for (int i = 0; i < N; i++) {
        int v; cin >> v;
        prefixSum[i + 1] = prefixSum[i] + v;
    }

    while(M--) {
        int i, j; cin >> i >> j; // i와 j는 1부터 시작하므로, (j + 1) (i) -> (j) (i - 1)
        cout << prefixSum[j] - prefixSum[i - 1] << "\n";
    }
}

2차원 구간 합 (Immutable)

2차원 누적 합 SS 정의

S[x+1][y+1]=i=0xj=0yA[i][j]S[x+1][y+1] = \sum_{i=0}^{x} \sum_{j=0}^{y} A[i][j]
  • S[i][j]S[i][j]는 좌상단 (0,0)(0,0)부터 (i1,j1)(i-1,j-1)까지의 부분 합

2차원 구간 합 A[L,R]A[L, R] 정의

x=x1x2y=y1y2A[x][y]=S[x2+1][y2+1]S[x2+1][y1]S[x1][y2+1]+S[x1][y1]\sum_{x = x_1}^{x_2} \sum_{y = y_1}^{y_2} A[x][y] = S[x_2+1][y_2+1] - S[x_2+1][y_1] - S[x_1][y_2+1] + S[x_1][y_1]

#include <bits/stdc++.h>
using namespace std;

int main() {
    int N, M; cin >> N >> M;
    vector<vector<int>> prefixSum(N + 1, vector<int>(N + 1, 0));
    
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            int v; cin >> v;
            prefixSum[i + 1][j + 1] = prefixSum[i + 1][j] + prefixSum[i][j + 1] 
                                        - prefixSum[i][j] + v;
        }
    }

    while(M--) {
        int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2; // x1, y1, x2, y2는 1부터 시작
        cout << prefixSum[x2][y2] - prefixSum[x2][y1 - 1] - prefixSum[x1 - 1][y2] + prefixSum[x1 - 1][y1 - 1] << "\n";
    }
}

0개의 댓글