Блог пользователя machine_solution

Автор machine_solution, 3 недели назад, По-русски

Всем привет!

Сегодняшний пост посвящён задаче F с недавнего Div 1 + Div 2 раунда. Она стала локальной знаменитостью, потому что является более решаемой задачей, чем задача Е того же раунда. А сегодня мы разберёмся, почему же эта задача такая простая

Итак, переходим к задаче. В ней для каждого отсортированного массива $$$a$$$ с элементами от $$$1$$$ до $$$m$$$ нужно посчитать суммарное количество итераций, за которое стандартный бинпоиск находит в массиве каждый элемент от $$$1$$$ до $$$m$$$. В задаче эта сумма описана как $$$f(a,1,1,n)+f(a,2,1,n)+\ldots+f(a,m,1,n)$$$. Ограничение: $$$n, m \leq 10^6$$$

Давайте попробуем что-то понять про количество итераций бинпоиска в зависимости от искомого числа $$$k$$$. Интуиция подсказывает, что на всех массивах бинпоиск будет вести себя регулярным образом, нужно это лишь формализовать. Для того, чтобы быстрее нащупать идею, давайте немного упростим задачу и будем считать, что все числа в массиве $$$a$$$ различны. Это действительно удобно, так как в таком случае у каждого элемента $$$k$$$ в массиве есть единственное вхождение, на котором остановится бинпоиск, если будет его искать.

Итак, мы сделали удобное предположение того, что все числа различные и мы знаем, что у каждого числа $$$k$$$ в массиве есть своя позиция, обозначим её за $$$pos[k]$$$. Если число $$$k$$$ не встречается в массиве $$$a$$$, то оно не влияет на сумму, так что такие случаи можно не рассматривать.

Вопрос 1: Как же посчитать $$$f(a,k,1, n)$$$ в таком случае?

Подсказка 1.1
Ответ 1.1
Подсказка 1.2
Ответ 1.2

Итак, мы научились для одного массива считать значение $$$f(a,k,1, n)$$$ для любого $$$k$$$ и даже поняли некоторые особенности, которые позволяют свернуть сумму и посчитать её "на листочке"

Вопрос 2: Как же посчитать сумму $$$f(a,k,1, n)$$$ по всем $$$k$$$ в отсортированном массиве из различных элементов?

Подсказка 2.1
Ответ 2.1
Подсказка 2.2
Ответ 2.2

Теперь наших идей достаточно, чтобы вернуться к общему случаю

Вопрос 3: Как теперь посчитать сумму для всех массивов $$$a$$$, а не только для строго возрастающих?

Подсказка 3.1
Ответ 3.1
Подсказка 3.2
Ответ 3.2
Подсказка 3.3
Ответ 3.3

Итак, мы научились считать сумму для всех массивов, давайте оценим время работы:

Так как нам понадобятся C-шки с индексами порядка $$$n + m$$$, мы за $$$O(n + m)$$$ посчитаем все факториалы и обратные факториалы для быстрых вычислений. Я в своём решении предподсчитал факториалы до $$$2 \cdot 10^6$$$ перед всеми мультитестами. И само решение для каждой позиции считает сколько шагов нужно, чтобы бинпоиск до неё дошёл, а также количество массивов, для которых бинпоиск остановится на ней. Всё это суммарно за $$$O(n)$$$. Значит итоговое время работы $$$O(n + m)$$$

Как видите, в здааче не было большого числа идей и она не зря была так популярна на раунде. Надеюсь, вам понравился этот разбор и принёс пользу

Замечание: Если Вам понравился это пост, то, возможно, Вам понравится контент из телеграм канала, в который я выкладываю свою подготовку к финалу ICPC 2026. Переходите по ссылке

  • Проголосовать: нравится
  • +3
  • Проголосовать: не нравится