Я бы использовал многомасштабную сеточную схему (эквивалентную четырем деревьям в той или иной форме).
Я предполагаю, что вы используете целые координаты (то есть пиксели) и имеете достаточно места для хранения всех пикселей.
Имейте массив списков прямоугольников, по одному для каждого пикселя. Затем, два раза в два, и сделайте это снова. И снова, и снова, и снова, пока у вас нет одного пикселя, который покрывает все.
Теперь ключ заключается в том, что вы вставляете прямоугольники на уровне, соответствующем размеру прямоугольника. Это будет что-то вроде (размер пикселя) ~ = min (высота, ширина)/2. Теперь для каждого прямоугольника у вас есть только несколько вложений, которые нужно сделать в списках (вы могли бы связать их выше константой, например, выбрать что-то, что имеет от 4 до 16 пикселей).
Если вы хотите искать все прямоугольники в x, y, вы смотрите в списке наименьшего пикселя, а затем в списке двухъядерного пикселя 2x2, который содержит его, а затем в формате 4x4 и т. Д .; вы должны иметь шаги log2 (количество пикселей) для просмотра.(Для больших пикселей вам нужно проверить, действительно ли (x, y) находится в прямоугольнике, вы ожидаете, что примерно половина из них будет успешной на границах, и все они будут успешными внутри прямоугольника, поэтому вы ожидаете не хуже, чем в 2 раза больше работы, чем если бы вы напрямую посмотрели на пиксель.)
Теперь, как насчет вставки? Это очень недорого - O (1), чтобы встать на передний план списка.
Как насчет удаления? Это дороже; вам нужно просмотреть и исцелить каждый список для каждого введенного вами пикселя. Это примерно O (n) в количестве прямоугольников, перекрывающихся в этой позиции в пространстве и примерно такого же размера. Если у вас действительно большое количество прямоугольников, вы должны использовать другую структуру данных для их хранения (хеш-набор, дерево RB и т. Д.).
(Обратите внимание, что если ваш самый маленький прямоугольник должен быть больше пикселя, вам не нужно фактически формировать многомасштабную структуру вплоть до уровня пикселей, просто спуститесь, пока самый маленький прямоугольник не будет безнадежно потерян внутри вашего пикселя binned.)
Возможно, мне что-то не хватает, но как у вас есть вставки в сублинейное время? Простое считывание координат каждого прямоугольника уже является операцией O (n). –
Если «экран» имеет все объекты, индексированные (kd, quad, r/trees), вставка должна быть
TheCloudlessSky
Если есть ограничение на то, как быстро прямоугольники могут двигаться, тогда небезосновательно спросить, есть ли способ амортизировать процесс восстановления. – user287792