펜윅 트리(BIT) 누적합 계산기
배열을 넣으면 펜윅 트리를 만들어 누적합 질의와 점 갱신이 타는 인덱스 사슬을 보입니다. 칸마다 2진 표기와 i & (−i) 값을 나란히 놓아, 이 자료구조가 사실상 그 한 줄로 굴러간다는 것을 눈으로 확인할 수 있습니다.
쉼표나 공백으로 나눠 적습니다. 32개까지, 음수·소수도 됩니다. 자리는 1번부터 셉니다.
1번부터 13번까지 더합니다.
1번부터 13번까지의 합
91
3칸만 보고 답했습니다. 하나씩 더했다면 13번 더해야 합니다. 걸음 수는 13을 2진수로 썼을 때 1비트의 개수와 같습니다.
질의 — i를 줄여 가며
| i | 2진수 | lowbit | 칸 값 | 누계 |
|---|---|---|---|---|
| 13 | 01101 | −1 | 13 | 13 |
| 12 | 01100 | −4 | 42 | 55 |
| 8 | 01000 | −8 | 36 | 91 |
질의는 i −= i & (−i)로 맨 아래 1비트를 하나씩 떼어 냅니다. 2진수 열에서 오른쪽 1이 한 번에 하나씩 사라지는 것이 보입니다. 그래서 걸음 수가 곧 1비트의 개수이고, 어떤 i에서도 log₂n을 넘지 않습니다.
갱신 — i를 늘려 가며
| i | 2진수 | lowbit | 고친 뒤 값 |
|---|---|---|---|
| 5 | 00101 | +1 | 15 |
| 6 | 00110 | +2 | 21 |
| 8 | 01000 | +8 | 46 |
| 16 | 10000 | +16 | 146 |
갱신은 i += i & (−i)로, 질의와 부호가 반대입니다. 나를 품는 더 큰 칸으로 올라가며 4칸을 고칩니다. 누적합 배열이었다면 12칸을 전부 고쳐야 합니다. 이 두 줄의 방향이 반대라는 것이 처음 볼 때 가장 헷갈리는 자리입니다.
각 칸이 맡는 구간
| i | 2진수 | lowbit | 맡는 구간 | 담긴 값 |
|---|---|---|---|---|
| 1 | 00001 | 1 | 1 ~ 1 | 1 |
| 2 | 00010 | 2 | 1 ~ 2 | 3 |
| 3 | 00011 | 1 | 3 ~ 3 | 3 |
| 4 | 00100 | 4 | 1 ~ 4 | 10 |
| 5 | 00101 | 1 | 5 ~ 5 | 5 |
| 6 | 00110 | 2 | 5 ~ 6 | 11 |
| 7 | 00111 | 1 | 7 ~ 7 | 7 |
| 8 | 01000 | 8 | 1 ~ 8 | 36 |
| 9 | 01001 | 1 | 9 ~ 9 | 9 |
| 10 | 01010 | 2 | 9 ~ 10 | 19 |
| 11 | 01011 | 1 | 11 ~ 11 | 11 |
| 12 | 01100 | 4 | 9 ~ 12 | 42 |
| 13 | 01101 | 1 | 13 ~ 13 | 13 |
| 14 | 01110 | 2 | 13 ~ 14 | 27 |
| 15 | 01111 | 1 | 15 ~ 15 | 15 |
| 16 | 10000 | 16 | 1 ~ 16 | 136 |
i번 칸은 원소 i−lowbit(i)+1부터 i까지, 곧 맨 아래 1비트만큼의 구간을 맡습니다. 홀수 칸은 자기 하나만, 4의 배수 칸은 넷을, 16번 칸은 열여섯을 맡습니다. 파랗게 칠한 줄이 지금 질의가 들른 칸입니다.
사용 방법
- 1배열을 쉼표나 공백으로 나눠 적습니다. 자리는 1번부터 셉니다.
- 2「어디까지의 합」을 정하면 질의가 들르는 칸이 표로 나옵니다.
- 32진수 열에서 오른쪽 1이 한 번에 하나씩 사라지는 것을 따라갑니다.
- 4「바꿀 자리」와 「더할 값」을 넣어 갱신이 타는 사슬을 봅니다. 질의와 방향이 반대입니다.
- 5맨 아래 표에서 각 칸이 원소 몇 번부터 몇 번까지를 맡는지 확인합니다.
자주 묻는 질문
i를 2진수로 썼을 때 맨 아래 1비트만 남긴 값입니다. 2의 보수에서 −i는 i의 비트를 뒤집고 1을 더한 값이라 두 수를 AND하면 그 비트만 살아남습니다. 12 = 1100₂이면 12 & (−12) = 100₂ = 4입니다. 펜윅 트리에서 하는 일은 사실상 이 한 줄이 전부입니다.
하는 일이 반대이기 때문입니다. 갱신은 i += i & (−i)로 나를 품는 더 큰 칸으로 올라가며 그 칸들의 값을 고치고, 질의는 i −= i & (−i)로 맡은 구간을 떼어 내며 앞으로 내려갑니다. 부호가 반대인 이 두 줄이 처음 볼 때 가장 헷갈리는 자리입니다.
질의의 걸음 수가 i의 2진수에 있는 1비트의 개수와 같기 때문입니다. 맨 아래 1비트를 하나씩 떼어 내므로 1이 몇 개인지가 곧 걸음 수이고, 그 개수는 자릿수를 넘을 수 없어 log₂n 이하입니다. 13 = 1101₂이면 세 걸음(13 → 12 → 8 → 0)이고, 32처럼 2의 거듭제곱이면 한 걸음이면 끝납니다.
질의만 있다면 그쪽이 낫습니다. 누적합 배열은 질의가 O(1)이지만 값 하나가 바뀌면 그 뒤를 전부 고쳐야 해서 갱신이 O(n)입니다. 펜윅 트리는 둘 다 O(log n)으로 맞춥니다. 값이 자주 바뀌면서 구간 합도 자주 물어야 할 때 값어치가 있습니다.
쓸 수 없습니다. 구간 합 질의가 「r까지의 합 − (l−1)까지의 합」이라는 뺄셈에 기대고 있어서 연산에 역원이 있어야 하는데, 최솟값에는 「빼기」가 없기 때문입니다. min(a, b)를 알아도 a를 되돌릴 수 없습니다. XOR처럼 역원이 자기 자신인 연산은 되고, 곱셈은 0이 끼면 안 됩니다. 구간 최솟값·최댓값이 필요하면 세그먼트 트리를 씁니다.
lowbit(0) = 0이라 0번을 쓰면 갱신 고리가 제자리에 갇히기 때문입니다. i += 0은 i를 그대로 두므로 무한 반복이 됩니다. 그래서 트리 배열은 1번부터 쓰고, 0번 칸은 비워 둡니다.
전송되지 않습니다. 모든 계산은 브라우저 안에서 이뤄지고, 입력값은 이 기기에만 남습니다.
알아두면 좋은 점
- 검증은 무작위 배열 500벌의 모든 자리에서 누적합을 하나씩 더한 값과 대조해 했습니다. 구간 합, 음수·소수가 섞인 경우도 함께 맞췄습니다.
- 질의 걸음 수가 i의 2진수에 있는 1비트 개수와 정확히 같은지, 13이면 13 → 12 → 8 → 0으로 세 걸음인지 테스트로 고정해 두었습니다.
- 갱신 사슬에 오르는 칸이 실제로 그 원소를 맡고 있는 칸과 정확히 일치하는지도 무작위 입력으로 확인했습니다. 트리를 한 번에 만드는 방식과 빈 트리에 하나씩 더해 만드는 방식이 같은 배열을 내는 것도 대조했습니다.
- 구간 최솟값에는 쓸 수 없습니다. 질의가 뺄셈에 기대고 있어 연산에 역원이 필요하기 때문입니다.
- 원소 32개까지 다룹니다. 칸마다 2진 표기와 맡은 구간을 모두 보이는 것이 목적이라 그보다 크면 화면이 읽히지 않습니다.
함께 보면 좋은 도구
마지막 검증: 2026년 9월 1일 · 결과는 참고용 추정치입니다.