Полка с учебниками: первый не ниже

тема: Двоичный поиск · уровень: базовый

Условие

В школьной библиотеке на полке стоят учебники по неубыванию высоты (от самых низких к самым высоким). Дежурному часто нужно быстро найти, где начинается «достаточно высокий» учебник для очередной обложки.

Для каждого запроса с числом x найди первую позицию на полке, где высота учебника не меньше x.

Если такого учебника нет (все ниже x), выведи 0.

Формат ввода

В первой строке даны два целых числа n и q — число учебников на полке и число запросов. Во второй строке даны n целых чисел a1, a2, ..., an — высоты учебников. Гарантируется, что a1 ≤ a2 ≤ ... ≤ an. В следующих q строках дано по одному целому числу x — запрос.

Формат вывода

Выведи q строк. В каждой строке выведи одно число — минимальный индекс i (нумерация с 1), такой что ai ≥ x. Если такого i не существует, выведи 0.

Ограничения

Пример

Ввод

5 4
1 3 3 7 10
0
3
4
11

Вывод

1
2
4
0

Как решать — идея подхода

Приём: Двоичный поиск (lower_bound)

Ключевое наблюдение: массив высот отсортирован по неубыванию. Значит, если на какой-то позиции высота уже ≥ x, то и все правее тоже ≥ x. И наоборот: если a[i] < x, то все левее точно не подходят. Это ровно ситуация для двоичного поиска по «границе».

Нужно найти первый подходящий элемент — это стандартная версия двоичного поиска lower_bound: ищем минимальный индекс i, где условие a[i] >= x становится истинным.

План решения:

Мини-сниппет правила сдвига: if a[m] >= x: r = m else: l = m + 1

Сложность: на один запрос O(log n), на все запросы O(q log n), памяти O(1) сверх массива.

Частая ошибка: путать границы (делать [l, r] вместо [l, r)) и из-за этого получать бесконечный цикл или ответ «второй подходящий» при равных элементах (например, для x=3 в [1,3,3,7] нужно вернуть первый 3).

Решить задачу с автопроверкой на Python →

Куда дальше