Это действительно можно сделать O(log(n)), O(log(n))
.
Хитрость заключается в том, чтобы дерево представляло собой структуру данных со следующими частями информации на каждом узле:
- startиндекс
- конечный индекс
- левый узел
- правый узел
- сколько 0 мод (3)
- сколько 1 мод (3)
- Сколько 2 мода (3)
- Сумма не примененного обновления
Когда вам говорят, что нужно применить обновление, вам нужно только применить его (и этонеприменимое количество) к узлам, имеющим границу внутри этого диапазона.В противном случае просто увеличьте количество непримененных обновлений.Вы будете лениво применять его, если вам когда-либо понадобится.
Когда вы запрашиваете диапазон, вы можете лениво применять неприменимое количество обновлений и извлекать данные из правой корзины, если у рассматриваемого диапазона нет границы внутри диапазонаиндексы в этой части дерева.Тогда, и только тогда, вам нужно внести неприменимое количество обновлений во внутренние узлы.
Обе операции развертывают только часть дерева на границе и поэтому O(log(n))
.