도구스개발

펜윅 트리(BIT) 누적합 계산기

배열을 넣으면 펜윅 트리를 만들어 누적합 질의와 점 갱신이 타는 인덱스 사슬을 보입니다. 칸마다 2진 표기와 i & (−i) 값을 나란히 놓아, 이 자료구조가 사실상 그 한 줄로 굴러간다는 것을 눈으로 확인할 수 있습니다.

쉼표나 공백으로 나눠 적습니다. 32개까지, 음수·소수도 됩니다. 자리는 1번부터 셉니다.

번까지

1번부터 13번까지 더합니다.

1번부터 13번까지의 합

91

3칸만 보고 답했습니다. 하나씩 더했다면 13번 더해야 합니다. 걸음 수는 13을 2진수로 썼을 때 1비트의 개수와 같습니다.

누적합91
검산 (하나씩 더한 값)91
펜윅 트리 걸음3칸
하나씩 더하면13번

질의 — i를 줄여 가며

i2진수lowbit칸 값누계
130110111313
120110044255
80100083691

질의는 i −= i & (−i)로 맨 아래 1비트를 하나씩 떼어 냅니다. 2진수 열에서 오른쪽 1이 한 번에 하나씩 사라지는 것이 보입니다. 그래서 걸음 수가 곧 1비트의 개수이고, 어떤 i에서도 log₂n을 넘지 않습니다.

갱신 — i를 늘려 가며

i2진수lowbit고친 뒤 값
500101+115
600110+221
801000+846
1610000+16146

갱신은 i += i & (−i)로, 질의와 부호가 반대입니다. 나를 품는 더 큰 칸으로 올라가며 4칸을 고칩니다. 누적합 배열이었다면 12칸을 전부 고쳐야 합니다. 이 두 줄의 방향이 반대라는 것이 처음 볼 때 가장 헷갈리는 자리입니다.

각 칸이 맡는 구간

i2진수lowbit맡는 구간담긴 값
10000111 ~ 11
20001021 ~ 23
30001113 ~ 33
40010041 ~ 410
50010115 ~ 55
60011025 ~ 611
70011117 ~ 77
80100081 ~ 836
90100119 ~ 99
100101029 ~ 1019
1101011111 ~ 1111
120110049 ~ 1242
1301101113 ~ 1313
1401110213 ~ 1427
1501111115 ~ 1515
1610000161 ~ 16136

i번 칸은 원소 i−lowbit(i)+1부터 i까지, 곧 맨 아래 1비트만큼의 구간을 맡습니다. 홀수 칸은 자기 하나만, 4의 배수 칸은 넷을, 16번 칸은 열여섯을 맡습니다. 파랗게 칠한 줄이 지금 질의가 들른 칸입니다.

2의 보수에서 −i는 i의 비트를 뒤집고 1을 더한 값이라, i & (−i)를 하면 맨 아래 1비트만 남습니다. 12 = 1100₂이면 12 & (−12) = 100₂ = 4입니다. 펜윅 트리에서 하는 일은 사실상 이 한 줄이 전부입니다.
구간 최솟값에는 쓸 수 없습니다. 질의가 「r까지의 합 − (l−1)까지의 합」 이라는 뺄셈에 기대고 있어서 연산에 역원이 있어야 하기 때문입니다. 합에는 뺄셈이 있지만 최솟값에는 「빼기」가 없습니다 — min(a, b)를 알아도 a를 되돌릴 수 없습니다. 구간 최솟값·최댓값이 필요하면 세그먼트 트리를 씁니다.

사용 방법

  1. 1배열을 쉼표나 공백으로 나눠 적습니다. 자리는 1번부터 셉니다.
  2. 2「어디까지의 합」을 정하면 질의가 들르는 칸이 표로 나옵니다.
  3. 32진수 열에서 오른쪽 1이 한 번에 하나씩 사라지는 것을 따라갑니다.
  4. 4「바꿀 자리」와 「더할 값」을 넣어 갱신이 타는 사슬을 봅니다. 질의와 방향이 반대입니다.
  5. 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일 · 결과는 참고용 추정치입니다.