Я думаю, что проблема ясно утверждает, что вы дали список размером N
, например
const int N = 15;
int xs[N] = {1, 3, 7, 9, 13, 16, 17, 19, 21, 24, 25, 26, 27, 28, 30};
Вы должны ответить на один запрос (менее чем O(logN)
), и, таким образом, вы не сможете выполнить какую-либо предварительную обработку. Я считаю, что в этом случае вопрос был бы сформулирован иначе, если бы вы могли пойти на амортизированные времена.
N
на практике может быть очень большим, поэтому даже самому числу N
может потребоваться много дисков для хранения (как я читаю вопрос:). Я думаю, это просто означает, что вы не можете создать простой поисковый массив размера M, потому что M > N
, следовательно, нет смысла.
Итак, на самом деле вы не можете сделать лучше, чем бинарный поиск. Однако, поскольку вы знаете максимально возможное значение элементов, равное M
(и при условии, что данные распределены равномерно), вы можете угадать начальную позицию, с которой следует начать бинарный поиск.
Это, по сути, x / M * N
, в коде может быть что-то вроде этого:
double hint = static_cast<double>(x) / M; // between [0,1)
int m = static_cast<int>(hint * N); // guess the position in xs
// do binary search using m as initial "middle" point.
Итак, это предположение, учитывая предположение, ускорит алгоритм на хорошую постоянную. Однако временная сложность все равно будет O(lgN)
.