Załóżmy, że masz pustą tablicę:
0 0 0 0 0 0 0 0 0 0 (array)
0 0 0 0 0 0 0 0 0 0 (cumulative sums)
I chciałeś zaktualizować zakres od +5 do [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)
Jak można przechowywać żądane sumy sumaryczne za pomocą 2 drzew indeksowanych binarnie?
Sztuką jest użycie dwóch drzew indeksowanych binarnie, BIT1 i BIT2, gdzie skumulowana suma jest obliczana na podstawie ich zawartości. W tym przykładzie oto, co chcielibyśmy przechowywać w dwóch drzewach:
0 0 0 5 5 5 5 5 0 0 (BIT1)
0 0 0 10 10 10 10 10 -25 -25 (BIT2)
Aby znaleźć sum[i]
, oblicz to:
sum[i] = BIT1[i] * i - BIT2[i]
Na przykład:
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
Aby osiągnąć pożądane wartości BIT1 i BIT2 dla poprzedniej aktualizacji zakresu, wykonujemy 3 aktualizacje zakresu:
Musimy dokonać aktualizacji zakresu +5 do wskaźników 3..7 dla BIT1.
Musimy dokonać aktualizacji zakresu +10 do wskaźników 3..7 dla BIT2.
Musimy dokonać aktualizacji zakresu -25 do indeksów 8..9 dla BIT2.
Teraz zróbmy jeszcze jedną transformację. Zamiast przechowywać wartości pokazane powyżej dla BIT1 i BIT2, w rzeczywistości przechowujemy ich skumulowane sumy. To pozwala nam wykonać powyższe 3 aktualizacje zakresu, dokonując 4 aktualizacji sum skumulowanych:
BIT1sum[3] += 5
BIT1sum[8] -= 5
BIT2sum[3] += 10
BIT2sum[8] -= 35
Ogólnie algorytm dodawania wartości v do zakresu [i..j] byłby:
BIT1sum[i] += v
BIT1sum[j+1] -= v
BIT2sum[i] += v * (i-1)
BIT2sum[j+1] -= v * j
gdzie składnia + = i - = oznacza po prostu aktualizację struktury danych zbiorczej sumy BIT o wartość dodatnią lub ujemną przy tym indeksie. Należy pamiętać, że aktualizacja skumulowanej BIT według indeksu ma domyślny wpływ na wszystkie indeksy po prawej stronie tego indeksu. Na przykład:
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])
Drzewa Fenwick przechowują sumy w drzewie binarnym. Uaktualnienia pokazane powyżej drzewa Fenwick można łatwo znaleźć wO ( logn ) czas.
sum[i] = BIT1[i] * i - BIT2[i]
? Wydaje się, że działa, ale wydaje się tak arbitralny ... jaki wgląd pozwala ci do tego dojść?