Verwenden Sie einen Segmentbaum - eine rekursive Aufteilung des Bereichs in kleinere Bereiche. Jedes Intervall [ a , b ] Ihrer Aktualisierungsvorgänge kann in O ( log n ) der Bereiche in dieser rekursiven Partition unterteilt werden. Für jeden Bereich [ x , y ] speichern Sie:[1,n][a,b]O(logn)[x,y]
- Die Anzahl der Intervalle [ a , b ] , die vergrößert und nicht verkleinert wurden, so dass [ x , y ] einer der Bereiche ist, in die [ a , b ] unterteilt istc(x,y)[a,b][x,y][a,b]
- Die Anzahl von Zellen, die nicht durch partitionierte Teilmengen von Intervallen abgedeckt sind , die in der Rekursion bei [ x , y ] oder darunter liegenu(x,y)[x,y]
Wenn dann rekursiv in [ x , z ] und [ z + 1 , w ] aufgeteilt wird , ist
u ( x , y ) = { 0, wenn c ( x , y ) > 0 u ( x , z ) + u ( z + 1 , y ) ansonsten[x,y][x,z][z+1,w]
u(x,y)={0u(x,z)+u(z+1,y)if c(x,y)>0otherwise
So können wir jeden
-Wert in konstanter Zeit aktualisieren
, wenn sich die anderen Daten für einen Bereich ändern. Jede Supportanfrage kann mit
u ( 1 , n ) beantwortet werden .
u(x,y)u(1,n)
Um eine Erhöhungsoperation durchzuführen, partitionieren Sie [ a , b ] in O ( log n ) -Bereiche, inkrementieren Sie c ( x , y ) für jeden dieser Bereiche und verwenden Sie die obige Formel, um u ( x , y) neu zu berechnen ) für jeden dieser Bereiche und für jeden ihrer Vorfahren. Die Verkleinerungsoperation ist dieselbe mit einer Verringerung anstelle einer Erhöhung.(a,b)[a,b]O(logn)c(x,y)u(x,y)