빈 배열이 있다고 가정하십시오.
0 0 0 0 0 0 0 0 0 0 (array)
0 0 0 0 0 0 0 0 0 0 (cumulative sums)
+5에서 [3..7]로 범위 업데이트를 원했습니다.
0 0 0 5 5 5 5 5 0 0 (array)
0 0 0 5 10 15 20 25 25 25 (desired cumulative sums)
2 개의 이진 인덱스 트리를 사용하여 원하는 누적 합계를 어떻게 저장할 수 있습니까?
비결은 2 개의 이진 색인 트리 인 BIT1과 BIT2를 사용하는 것입니다. 여기서 누적 합계는 내용에서 계산됩니다. 이 예에서 두 트리에 저장 한 내용은 다음과 같습니다.
0 0 0 5 5 5 5 5 0 0 (BIT1)
0 0 0 10 10 10 10 10 -25 -25 (BIT2)
를 찾으려면 sum[i]
이것을 계산하십시오.
sum[i] = BIT1[i] * i - BIT2[i]
예를 들면 다음과 같습니다.
sum[2] = 0*2 - 0 = 0
sum[3] = 5*3 - 10 = 5
sum[4] = 5*4 - 10 = 10
...
sum[7] = 5*7 - 10 = 25
sum[8] = 0*8 - (-25) = 25
sum[9] = 0*9 - (-25) = 25
이전 범위 업데이트에 대해 원하는 BIT1 및 BIT2 값을 달성하기 위해 3 가지 범위 업데이트를 수행합니다.
BIT1의 경우 지수 3..7에서 +5의 범위 업데이트를 수행해야합니다.
BIT2의 경우 지수 3..7로 +10의 범위 업데이트를 수행해야합니다.
BIT2의 경우 지수 8..9에서 -25의 범위 업데이트를 수행해야합니다.
이제 하나 더 변형을하겠습니다. BIT1 및 BIT2에 대해 위에 표시된 값을 저장하는 대신 실제로 누적 합계를 저장합니다. 이를 통해 누적 합계를 4 번 업데이트하여 위의 3 가지 범위 업데이트를 수행 할 수 있습니다.
BIT1sum[3] += 5
BIT1sum[8] -= 5
BIT2sum[3] += 10
BIT2sum[8] -= 35
일반적으로 값 v를 범위 [i..j]에 추가하는 알고리즘은 다음과 같습니다.
BIT1sum[i] += v
BIT1sum[j+1] -= v
BIT2sum[i] += v * (i-1)
BIT2sum[j+1] -= v * j
여기서 + = 및-= 구문은 단순히 해당 인덱스에서 BIT 누적 합계 데이터 구조를 양수 또는 음수 값으로 업데이트하는 것을 의미합니다. 인덱스에서 BIT 누적 합계를 업데이트하면 해당 인덱스 오른쪽의 모든 인덱스에 암시 적으로 영향을 미칩니다. 예를 들면 다음과 같습니다.
0 0 0 0 0 0 0 0 0 0 (original)
BITsum[3] += 5
0 0 0 5 5 5 5 5 5 5 (after updating [3])
BITsum[8] -= 5
0 0 0 5 5 5 5 5 0 0 (after updating [8])
Fenwick 트리는 이진 트리에 합계를 저장합니다. 위에 표시된 업데이트는 시간 에 Fenwick 트리에 쉽게 수행 할 수 있습니다 .O(logn)
sum[i] = BIT1[i] * i - BIT2[i]
? 작동하는 것처럼 보이지만 너무 임의적 인 것 같습니다 ...이 통찰력을 얻을 수있는 통찰력은 무엇입니까?