Utilisez une arborescence de segments - une partition récursive de la plage en plages plus petites. Chaque intervalle [ a , b ] de vos opérations de mise à jour peut être partitionné en O ( log n ) des plages de cette partition récursive. Pour chaque plage [ x , y ] magasin:[1,n][a,b]O(logn)[x,y]
- Le nombre d'intervalles [ a , b ] qui ont été augmentés et non diminués de telle sorte que [ x , y ] est l'une des plages dans lesquelles [ a , b ] est partitionnéc(x,y)[a,b][x,y][a,b]
- Le nombre de cellules qui ne sont pas couvertes par des sous-ensembles partitionnés d'intervalles qui sont à [ x , y ] ou moins dans la récursivitéu(x,y)[x,y]
Alors si est récursivement divisé en [ x , z ] et [ z + 1 , w ] nous avons
u ( x , y ) = { 0 si c ( x , y ) > 0 u ( x , z ) + u ( z + 1 , y ) sinon[x,y][x,z][z+1,w]
u(x,y)={0u(x,z)+u(z+1,y)if c(x,y)>0otherwise
afin que nous puissions mettre à jour chaque valeur
en temps constant lorsque les autres données d'une plage changent. Chaque requête de support peut être répondue en regardant
u ( 1 , n ) .
u(x,y)u(1,n)
Pour effectuer une opération d'augmentation , partitionnez [ a , b ] en plages O ( log n ) , incrémentez c ( x , y ) pour chacune de ces plages et utilisez la formule ci-dessus pour recalculer u ( x , y ) pour chacune de ces plages et pour chacun de leurs ancêtres. L'opération de diminution est la même avec un décrément au lieu d'un incrément.(a,b)[a,b]O(logn)c(x,y)u(x,y)