Estou procurando uma estrutura de dados que mantenha uma tabela inteira de tamanho e permita as seguintes operações no tempo .
- , que aumenta .
- , que diminui t [ a ] , t [ a + 1 ] , … , t [ b ] .
- , que retorna o número de índices i tal que t [ i ] ≠ 0 .
Você tem a promessa de que cada chamada para diminuir pode ser correspondida a uma chamada anterior para aumentar com os mesmos parâmetros . A aplicação que tenho em mente é um algoritmo de linha de varredura para calcular no tempo O ( n log n ) a área da união de n dados retângulos retilíneos.
Uma árvore quádrupla teria tamanho , portanto não é uma solução. As árvores Fenwick ou Interval têm o sabor certo, mas não vejo como estendê-las para apoiar as operações acima.
ds.data-structures
cg.comp-geom
Christoph Dürr
fonte
fonte
Respostas:
Use uma árvore de segmentos - uma partição recursiva do intervalo em intervalos menores. Cada intervalo [ a , b ] de suas operações de atualização pode ser particionado em O ( log n ) dos intervalos nessa partição recursiva. Para cada intervalo [ x , y ] de armazenamento:[ 1 , n ] [ a , b ] O ( logn ) [ x , y]
Então, se é dividido recursivamente em [ x , z ] e [ z + 1 , w ] , temos u ( x , y ) = { 0 se c ( x , y ) > 0 u ( x , z ) + u ( z + 1 , y ) caso contrário[ x , y] [ x , z] [ z+ 1 , w ]
Para executar uma operação de aumento , particione [ a , b ] em intervalos O ( log n ) , incremente c (( a , b ) [ a , b ] O ( logn ) para cada um desses intervalos e use a fórmula acima para recalcular u ( x , y ) para cada um desses intervalos e cada um de seus ancestrais. A operação de diminuição é a mesma com um decremento em vez de um incremento.c ( x , y) u ( x , y)
fonte
fonte