PS/Solve

[Java] Boj 11659: 구간 합 구하기 4

hyeon0117 2025. 2. 21. 17:58

문제

수 N개가 주어졌을 때, i번째 수부터 j번째 수까지 합을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 수의 개수 N과 합을 구해야 하는 횟수 M이 주어진다. 둘째 줄에는 N개의 수가 주어진다. 수는 1,000보다 작거나 같은 자연수이다. 셋째 줄부터 M개의 줄에는 합을 구해야 하는 구간 i와 j가 주어진다.

출력

총 M개의 줄에 입력으로 주어진 i번째 수부터 j번째 수까지 합을 출력한다.

제한

  • 1 ≤ N ≤ 100,000
  • 1 ≤ M ≤ 100,000
  • 1 ≤ i ≤ j ≤ N
  •  

풀이

배열의 구간 합을 구하면 되는 단순한 문제처럼 보이지만 N, M의 범위에 의해 이중 반복문을 사용한다면 시간 초과가 발생하게 된다.

따라서 이중 반복문이 아닌 다른 방법을 사용해야 하는데, 누적 합 개념을 이용해야 한다.

누적 합은 기존의 수를 저장할 배열 arr와 수들의 합을 저장할 배열 sum을 통해 구현할 수 있다.

arr에는 입력받는 수를 저장하고, sum 배열에는 입력받는 수들의 누적 합을 저장한다.

(arr에 1, 2, 3, 4, 5가 저장되면 sum 배열에는 1, 3, 6, 10, 15가 저장되는 방식)

이 방식을 이용하면 i부터 j까지의 구간 합을 이용하여 구할 수 있다.

여담으로, 누적 합 개념의 기본을 잡고 가기 좋은 문제이다.

 

sum[i] = arr[0] + arr[1] + ... + arr[i]

sum[j] = arr[0] + arr[1] + ... + arr[j]

 

위와 같이 sum 배열의 원소를 표현할 수 있는데, 여기서 sum[j] - sum[i] = arr[i + 1] + arr[i + 2] + ... + arr[j]이다. 

따라서 i부터 j까지의 구간 합은 sum[j] - sum[i - 1]로 표현할 수 있다.

 

이것 이외에 고려할 사항으로는 1) i = j인 경우, 2) i = 1인 경우, 3) 이외의 경우가 있다.

1)의 경우에는 구간 합을 고려할 필요 없이 arr 배열의 i 또는 j번째 원소를 결과로 출력하면 된다.

2)의 경우는 1 ~ j 까지의 구간 합을 구하는 것이므로 j까지의 구간 합을 구하면 된다.

3)은 위 식에서 구한 방식을 통해 결과를 출력하면 된다.

 

 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
 
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(bf.readLine());
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        int[] arr = new int[n + 1];
        int[] sum = new int[n + 1];
        st = new StringTokenizer(bf.readLine());
        for (int i = 1; i <= n; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
            if (i == 0) {
                sum[i] = arr[i];
            } else {
                sum[i] += sum[i - 1+ arr[i];
            }
        }
        for (int i = 0; i < m; i++) {
            st = new StringTokenizer(bf.readLine());
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
            if (x == 1) {
                System.out.println(sum[y]);
            } else if (x == y) {
                System.out.println(arr[y]);
            } else {
                System.out.println(sum[y] - sum[x-1]);
            }
        }
    }
}
cs