도구스개발

차분 배열(구간 갱신) 계산기

「구간에 값을 더하라」는 명령이 여러 개일 때 차분 배열의 두 칸만 건드리고 마지막에 누적합을 한 번 돌려 전부 처리합니다. 1차원 구간과 2차원 사각형을 모두 다루고, 닫는 자리를 빼먹었을 때 어떤 결과가 나오는지 나란히 보여 줍니다.

한 줄에 「왼쪽끝 오른쪽끝 더할값」. 칸 번호는 1부터 셉니다. 범위 밖이거나 순서가 뒤집힌 줄은 무시합니다.

쓰기 횟수

13번 → 16번

명령 3개를 곧이곧대로 적용하면 13칸을 씁니다. 차분 배열은 명령마다 2칸씩 6번 + 마지막 누적합 10번으로 끝냅니다.

명령 개수3개
배열 길이10칸
차분 배열 길이11칸 (마지막 1칸은 배열 밖)
쓰기가 줄어든 배수0.81배
전수 적용과 일치일치합니다

칸마다의 값

차분 d[i]누적합 = 결과전수 적용닫기를 빼먹으면
110101010
23131313
30131313
4-112212
502212
6-3-1-112
70-1-112
80-1-112
90-1-112
1010012
110배열 밖 — 누적합에 쓰이지 않습니다

마지막 줄이 «배열 밖» 자리입니다. 오른쪽 끝이 배열의 마지막 칸인 명령의 −v가 여기에 떨어집니다. 이 칸을 두지 않고 조건문으로 건너뛰려다 어긋나기 쉬워, 길이를 n+1로 잡는 편이 안전합니다.

명령마다 건드리는 두 칸

명령여는 자리닫는 자리건드린 칸 수
[2, 5] += 3d[2] += 3d[6] −= 32 (곧이곧대로면 4)
[4, 9] += -1d[4] += -1d[10] −= 12 (곧이곧대로면 6)
[1, 3] += 10d[1] += 10d[4] −= 102 (곧이곧대로면 3)
닫는 자리를 빼먹으면 구간이 끝나지 않습니다. 위 표의 마지막 열이 d[r+1] −= v를 빠뜨렸을 때의 결과입니다. 구간이 끝나야 할 자리에서 내려오지 못해 배열 끝까지 v가 계속 더해집니다. 이 자료구조에서 가장 흔한 버그이고, 구간이 어차피 배열 끝까지인 짧은 예제로 시험하면 결과가 같아 보여 그냥 지나갑니다.
구간 안쪽은 차이가 그대로라 건드릴 게 없습니다. 원래 배열 대신 이웃과의 차이 d[i] = a[i] − a[i−1]을 담아 두면, 구간에 v를 더해도 안쪽은 나란히 v씩 올라가 차이가 변하지 않습니다. 달라지는 곳은 올라가기 시작하는 자리와 도로 내려오는 자리, 경계 두 곳뿐입니다. 마지막에 누적합을 한 번 돌리면 원래 배열이 돌아옵니다.
갱신이 다 끝난 뒤에야 읽을 수 있습니다. 이 방법은 「명령을 전부 받고 → 마지막에 한 번 읽는」 경우에만 이깁니다. 갱신과 질의가 섞여 들어오면 읽을 때마다 누적합을 다시 돌려야 해서 이점이 사라집니다. 그럴 때는 펜윅 트리나 세그먼트 트리를 씁니다.

사용 방법

  1. 1배열 길이를 정하고, 한 줄에 하나씩 「왼쪽끝 오른쪽끝 더할값」으로 명령을 적습니다. 칸 번호는 1부터 셉니다.
  2. 2결과 표에서 차분 배열 d[i]가 경계 두 곳에서만 0이 아닌 것을 확인합니다.
  3. 3「닫기를 빼먹으면」 열과 견주어, d[r+1] −= v를 빠뜨렸을 때 구간이 끝나지 않는 것을 봅니다.
  4. 4「2차원 사각형」으로 바꾸면 모서리 네 칸만 건드려 같은 일을 하는 것을 볼 수 있습니다.
  5. 5쓰기 횟수에서 명령 개수가 늘수록 얼마나 벌어지는지 확인합니다.

자주 묻는 질문

원래 배열 대신 이웃과의 차이 d[i] = a[i] − a[i−1]을 담아 두는 배열입니다. 구간 [l, r]에 v를 더할 때 안쪽은 나란히 v씩 올라가 차이가 변하지 않으므로, d[l] += v와 d[r+1] −= v 두 칸만 고치면 됩니다. 마지막에 누적합을 한 번 돌리면 원래 배열이 돌아옵니다.

길이 n에 명령이 m개일 때 O(nm)이 O(n+m)이 됩니다. 곧이곧대로 하면 명령마다 구간 길이만큼 써야 하는데, 차분 배열은 명령마다 정확히 2번 쓰고 마지막에 누적합으로 n번 씁니다. 구간이 길고 명령이 많을수록 차이가 커집니다.

구간이 끝나지 않고 배열 끝까지 v가 계속 더해집니다. 이 자료구조에서 가장 흔한 버그이며, 구간이 어차피 배열 끝까지인 짧은 예제로 시험하면 결과가 같아 보여 그냥 지나가기 쉽습니다. 이 도구는 빼먹었을 때의 결과를 옆 열에 나란히 보여 줍니다.

오른쪽 끝이 배열의 마지막 칸인 명령의 −v가 떨어질 자리가 필요하기 때문입니다. 이 칸을 두면 r+1이 배열을 넘어가는 경우를 조건문 없이 똑같이 처리할 수 있고, 누적합을 돌릴 때는 그냥 쓰지 않으면 됩니다. 조건문으로 건너뛰려다 어긋나는 것보다 안전합니다.

모서리 네 칸을 건드립니다. 왼쪽 위에 +v, 오른쪽 바깥과 아래 바깥에 각각 −v, 두 번 뺀 오른쪽 아래 모서리에 다시 +v를 놓는 포함–배제입니다. 되살릴 때는 행 방향과 열 방향으로 누적합을 한 번씩 돌립니다. 마지막 +v를 빼먹으면 사각형의 오른쪽 아래 바깥이 −v만큼 잘못 깎입니다.

갱신과 질의가 섞이는지가 다릅니다. 차분 배열은 명령을 전부 받고 마지막에 한 번 읽는 경우에만 이깁니다. 읽을 때마다 누적합을 다시 돌려야 하기 때문입니다. 갱신 사이사이에 값을 물어보는 상황이라면 펜윅 트리나 세그먼트 트리를 써야 합니다.

「몇 시부터 몇 시까지 몇 명이 있었는가」처럼 구간이 겹쳐 쌓이는 문제에 그대로 쓰입니다. 회의실 동시 사용 인원, 도로 구간별 통행량 누적, 이미지에서 사각형 영역 여러 개를 한꺼번에 밝히기 같은 것이 모두 같은 계산입니다. 일본 경진대회 쪽에서는 이모스법(いもす法)이라고도 부릅니다.

전송되지 않습니다. 계산은 모두 브라우저 안에서 이루어지고 넣은 값은 이 기기에만 남습니다.

알아두면 좋은 점

  • 표를 보이기 위해 1차원은 40칸, 2차원은 12×12까지만 다룹니다. 알고리즘 자체는 크기 제한이 없습니다.
  • 칸 번호는 화면에서 1부터 셉니다. 코드로 옮길 때는 0부터 세는 관례가 흔하니 d[r+1] 자리를 다시 확인하세요.
  • 범위를 벗어나거나 왼쪽 끝이 오른쪽 끝보다 큰 명령은 무시합니다.
  • 결과가 정말 맞는지 확인하려고 전수 적용 결과를 같은 표에 함께 냅니다.

함께 보면 좋은 도구

마지막 검증: 2026년 9월 2일 · 결과는 참고용 추정치입니다.