Сжатие координат в дереве Фенвика
Допустим, у нас есть n пустых коробок подряд. Мы собираемся положить m групп монет в несколько последовательных коробок, которые известны заранее. Мы помещаем 1-ю группу монет в коробки от i_1 до j_1, 2-ю группу в коробки от i_2 до j_2 и так далее.
Позвольте быть c_i количество монет в коробке i, после помещения всех монет в коробки. Мы хотим, чтобы можно было быстро определить, сколько монет в коробках с индексами i = s, s + 1,... e - 1, e, т.е. мы хотим вычислить сумму
c_s +c_(s+1) + ... + c_e
эффективно. Это можно сделать с помощью дерева Фенвика. Без каких-либо улучшений дереву Фенвика требуется пространство O(n) для хранения c_i(в таблице; фактически, дерево [i]!= C_i, значения сохраняются умнее) и время O(log n) для вычисления верхней суммы.
Если у нас есть случай, когда
- n слишком велик, чтобы мы могли составить таблицу длины n (скажем, ~ 10 000 000 000)
- м достаточно мало (скажем, ~ 500 000)
есть способ как-то сжимать координаты (индексы) блоков, то есть достаточно хранить только блоки с индексами i_1, i_2,..., i_m. Поскольку значение, хранящееся в дереве [i], зависит от двоичного представления i, моя идея состоит в том, чтобы отсортировать индексы i_1, j_1, i_2, j_2,..., i_m, j_m и создать дерево длиной O (m). Добавление нового значения в дерево будет простым. Кроме того, чтобы вычислить эту сумму, нам нужно только найти первый индекс, который не больше, чем e, и последний, который не меньше, чем s. И то, и другое можно сделать с помощью бинарного поиска. После этого сумма может быть легко вычислена.
Проблема возникает в 2D случае. Теперь у нас есть область точек (x,y) на плоскости, 0
How to store coordinates in the tree in a more efficient way?
Решения проблемы, использующие деревья Фенвика, являются предпочтительными, но любое решение приветствуется!
1 ответ
- Самый простой подход - использовать map / unordered_map вместо 2d-массива. В этом случае вам даже не нужно сжатие координат. Карта создаст пару ключ-значение только тогда, когда это необходимо, поэтому она создает log^2(n) пар ключ-значение для каждой точки ввода.
- Также вы можете сегментировать дерево на основе указателей (вместо массивов) с отложенной инициализацией (вы должны создавать узел только тогда, когда это необходимо).
- Используйте 2d Segment Tree. Можно заметить, что для каждого канонического сегмента по y-координате вы можете построить дерево сегментов (1d) для x-координат только для точек, лежащих в зоне y_min <= y