Questo risolve il problema solo per intervalli contigui. Non risolve sottosequenze arbitrarie. :-(
E 'possibile implementare questa con il tempo O(1)
per l'intervallo e O(log(n))
per change
.
Prima di tutto avremo bisogno di un mucchio per tutti gli intervalli di corrente, con la più grande sulla parte superiore. trovare l'intervallo più lungo è solo una questione di guardare in cima al mucchio.
successivo abbiamo bisogno di un po 'di informazioni per ciascuno dei nostri n
slot.
value: Current value in this slot
interval_start: Where the interval containing this point starts
interval_end: Where the interval containing this point ends
heap_index: Where to find this interval in the heap NOTE: Heap operations MUST maintain this!
E ora il trucco intelligente! Noi sempre memorizzare il valore per ogni slot. Ma noi solo memorizziamo le informazioni sull'intervallo per un intervallo nel punto dell'intervallo il cui indice è divisibile per la massima potenza di 2. C'è sempre un solo punto per ogni intervallo, quindi archiviare/modificare questo è pochissimo lavoro.
Quindi per capire a quale intervallo si trova attualmente una determinata posizione nell'array, dobbiamo guardare tutti i vicini che stanno aumentando i poteri di 2 finché non troviamo l'ultimo con il nostro valore. Quindi, per esempio, le informazioni sulla posizione 13
possono essere trovate in una qualsiasi delle posizioni 0, 8, 12, 13, 14, 16, 32, 64, ....
(E prendiamo il primo intervallo che troviamo nella lista 0, ..., 64, 32, 16, 8, 12, 14, 13
.) Questa è una ricerca di una lista O(log(n))
così è O(log(n))
lavoro .
Ora come implementiamo change
?
- Valore di aggiornamento.
- Calcola l'intervallo in cui ci trovavamo e se eravamo a un limite di intervallo.
- Se gli intervalli sono stati modificati, rimuovere quelli vecchi dall'heap. (Possiamo rimuovere 0, 1 o 2)
- Se gli intervalli cambiano, inserire i nuovi nell'heap.(Possiamo inseriamo 0, 1 o 2)
Tale aggiornamento è molto complessa, ma è un numero fisso di O(log(n))
operazioni e quindi dovrebbe essere O(log(n))
.
Intendevi una sottosequenza contigua? –
No, intendevo una sottosequenza generale, penso che il caso contiguo sia molto più semplice. – qiubit
Ho pensato tanto, ma volevo essere sicuro prima di provare a fare la testa o la coda della risposta di valdem –