Use un árbol de segmentos: una partición recursiva del rango en rangos más pequeños. Cada intervalo de sus operaciones de actualización puede dividirse en de los rangos en esta partición recursiva. Para cada rango almacenar:[ a , b ] O ( log n ) [ x , y ][1,n][a,b]O(logn)[x,y]
- El número de los intervalos que se han aumentado y no disminuido de tal manera que es uno de los rangos en la que se repartió[ a , b ] [ x , y ] [ a , b ]c(x,y)[a,b][x,y][a,b]
- El número de celdas que no están cubiertas por subconjuntos particionados de intervalos que están en o menos en la recursividad[ x , y ]u(x,y)[x,y]
Entonces, si se divide recursivamente en y tenemos
para que podamos actualizar cada valor de en tiempo constante cuando los otros datos para Un rango cambia. Cada consulta de soporte puede responderse mirando .[ x , z ] [ z + 1 , w ] u ( x , y ) = { 0 si c ( x , y ) > 0 u ( x , z ) + u ( z + 1 , y ) de lo contrario u ( x , y ) u ( 1[x,y][x,z][z+1,w]
u(x,y)={0u(x,z)+u(z+1,y)if c(x,y)>0otherwise
u(x,y)u(1,n)
Para realizar una operación de aumento , particione en rangos , incremente para cada uno de estos rangos y use la fórmula anterior para recalcular para cada uno de estos rangos y cada uno de sus antepasados. La operación de disminución es la misma con una disminución en lugar de un incremento.(a,b)[a,b]O(logn)c(x,y)u(x,y)