Теоретически, дерево Ван Эмде Боаса - ваша лучшая ставка с операциями времени O (log log M), где M - размер диапазона.Использование пространства довольно велико, хотя есть и более эффективные варианты.
На самом деле теоретический уровень техники описан в статье Об отчете о дальности в одном измерении , Мортенсена, Паг и Патраску.
Я не уверен, что существующие нижние границы исключают O (1), но M не будет достаточно большим, чтобы сделать различие существенным.Вместо структуры vEB я бы просто использовал k-арное дерево со степенью k, равной двум, например 32 или 64.
РЕДАКТИРОВАТЬ: вот один из способов поиска по диапазону с помощью дерева.
Давайте предположим, что каждый элемент данных является небольшим шаблоном (достаточно просто; так думает процессор).Каждое поддерево состоит из всех узлов с определенным префиксом.Например, {0000, 0011, 0101, 1001} представлен следующим 4-мя числами, где X
обозначает нулевой указатель.
+---+---+---+---+
|00\|01\|10\|11X|
+--|+--|+--|+---+
| | |
| | +----------------------------+
+--+ | |
| +------------+ |
| | |
v v v
+---+---+---+---+ +---+---+---+---+ +---+---+---+---+
|00\|01X|10X|11\| |00X|01\|10X|11X| |00X|01\|10X|11X|
+--|+---+---+--|+ +---+--|+---+---+ +---+--|+---+---+
| | | |
v v v v
0000 0011 0101 1001
Пара оптимизаций быстро становится очевидной.Во-первых, если все битовые комбинации имеют одинаковую длину, нам не нужно хранить их на листьях - их можно восстановить по траектории спуска.Все, что нам нужно, это битовая карта, которая, если k - это число битов в машинном слове, хорошо вписывается туда, где раньше был указатель с предыдущего уровня.
+--------+--------+--------+--------+
|00(1001)|01(0100)|10(0100)|11(0000)|
+--------+--------+--------+--------+
Для поиска по деревудиапазон, как [0001, 1000], мы начинаем с корня, определяем, какие поддеревья могут пересекать диапазон, и рекурсировать по ним.В этом примере соответствующие дочерние элементы корня - 00, 01 и 10. Соответствующие дочерние элементы 00 - это поддеревья, представляющие префиксы 0001, 0010 и 0011.
Для фиксированного значения k, отправка отчета из k-три три - O (log M + s), где M - количество битовых комбинаций, а s - количество совпадений.Не обманывайте себя - когда k средний, каждый узел занимает пару строк кеша, но время не очень велико, поэтому количество пропусков кеша довольно мало.