연병장은 1번부터 N번까지 일렬로 이루어진 칸이다.
각 칸에는 높이가 존재한다.
조교들은 다음과 같은 명령을 내린다.
[a, b] 구간에 k만큼 더하거나 빼라
모든 명령을 수행한 뒤
각 칸의 최종 높이를 구하는 문제이다.
첫째 줄
N M
둘째 줄
초기 높이
다음 M줄
a b k
조건
1 ≤ N, M ≤ 100,000
최종 높이를 출력
10 3
1 2 3 4 5 -1 -2 -3 -4 -5
1 5 -3
6 10 5
2 7 2
-2 1 2 3 4 6 5 2 1 0
이 문제의 핵심은 다음이다.
구간 업데이트를 빠르게 처리
단순하게 구현하면
[a, b] 구간을 매번 직접 업데이트
→ O(N × M)
최대
100,000 × 100,000 = 10^10
→ 시간초과
차분 배열 (Difference Array)
을 사용한다.
import java.util.Scanner;
class Main
{
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int M = sc.nextInt();
int[] origin = new int[N + 1];
for (int i = 1; i <= N; i++)
origin[i] = sc.nextInt();
int[] delta = new int[N + 2];
while (M-- > 0) {
int a = sc.nextInt();
int b = sc.nextInt();
int k = sc.nextInt();
delta[a] += k;
delta[b + 1] -= k;
}
int[] accDelta = new int[N + 1];
for (int i = 1; i <= N; i++)
accDelta[i] = accDelta[i - 1] + delta[i];
for (int i = 1; i <= N; i++)
System.out.print(origin[i] + accDelta[i] + " ");
System.out.println();
}
}
import java.util.Scanner;
class Main
{
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int M = sc.nextInt();
int[] origin = new int[N + 1];
for (int i = 1; i <= N; i++)
origin[i] = sc.nextInt();
int[] delta = new int[N + 2];
while (M-- > 0) {
int a = sc.nextInt();
int b = sc.nextInt();
int k = sc.nextInt();
delta[a] += k;
delta[b + 1] -= k;
}
int[] accDelta = new int[N + 1];
for (int i = 1; i <= N; i++)
accDelta[i] = accDelta[i - 1] + delta[i];
for (int i = 1; i <= N; i++)
System.out.print(origin[i] + accDelta[i] + " ");
System.out.println();
}
}
완전히 동일한 코드
→ 풀이 방식 차이 없음
두 코드 모두 동일하게
delta[a] += k;
delta[b + 1] -= k;
를 사용한다.
accDelta[i] = accDelta[i-1] + delta[i];
→ 구간 영향 적용
없음 (완전히 동일)
구간 업데이트를 빠르게 처리하는 기법
delta[a] += k
delta[b+1] -= k
a부터 시작해서 +k
b 이후부터 -k
accDelta[i] = accDelta[i-1] + delta[i]
→ 실제 값 복원
origin[i] + accDelta[i]
전체
O(N + M)
이 문제는 단순 구현 문제가 아니라
구간 업데이트 최적화 문제였다.
핵심은 다음이다.
차분 배열 + 누적합
내 코드와 강의 코드는 완전히 동일하며,
핵심 개념을 정확히 이해하고 구현한 상태이다.
이 문제를 통해 얻을 수 있는 중요한 포인트는 다음과 같다.
즉,
구간 문제 = 차분 배열 or 누적합
이라는 것을 반드시 기억해야 한다.