Всем Привет!

Меня зовут Максим и я очень давно хочу достичь рейтинга 3000. Я верю, что для этого мне надо научиться мыслить, как человек, у которого уже есть 3000 рейтинга. Очень часто в разборах пишут фразы "заметим, что..." или "докажем вот такой факт..." и дальше идет долгое доказательство этого факта. А то, каким образом я должен к этому факту прийти, как эта мысль должна зародиться у меня в голове, никто нигде не пишет. Я думаю, что не только у меня есть эта проблема, поэтому вместо того, чтобы ждать понятный разбор, я решил начать с себя. Именно поэтому, я решил написать очередной пошаговый разбор, где я буду описывать ход своих мыслей и действий, которые позволяют мне придумать эти самые идеи.
Также, я создал группу по прокачке навыков спортивного программирования для людей с рейтингом 1200- , чтобы помочь им стать лучше и достигнуть рейтинга 1500+. Если хотите больше об этом узнать, рекомендую прочитать ЭТОТ ПОСТ или заполнить ФОРМУ. Эту группу я назвал Polaris в честь путеводной звезды. В Polaris ребята решают специально подобранные контесты под их уровень, дорешивают их с помощью пошаговых разборов, изучают новую теорию, решают специально подготовленные для них подводящие упражнения, а также получают подробные рекомендации на основе их участия в тренировочных контестах. Более того, специально для участников группы я делаю пошаговые разборы тех задач, которые интересны самим участникам. Также, в группе регулярно ведется обсуждение прошедших контестов, а в ближайшем будущем мы будем готовиться к предстоящим олимпиадам (как школьным, так и студенческим). Присоединяйтесь, я буду вам очень рад!
А теперь перейдем к самому разбору контеста. Но перед этим, я бы хотел ввести несколько правил чтения разбора для того, чтобы вы смогли получить максимум пользы от него.
- Перед чтением разбора задачи, убедитесь, что вы прочитали задачу, подумали над ней, извлекли из своей головы и записали/нарисовали максимальное количество идей и больше уже ничего не можете придумать.
- Во время чтения разбора, если в какой-то момент, какое-то предложение в разборе навело вас на новую мысль, перестаньте читать разбор и вернитесь к пункту (1), а именно продолжите с этого места генерировать новые идеи. Это очень важно.
- Если вы дочитали текст разбора до конца и не поняли, как решать задачу или остались вопросы, то их нужно обязательно задать в комментариях или спросить в Polaris. Там вам помогут я и ребята, кто справился с этой задачей. Также в этом случае, полезно прочитать код, который будет прикреплен к разбору.
- После того, как вы решили задачу, обязательно посмотрите код других участников и код с разбора. Возможно, он наведет вас на мысль о том, как можно было проще и быстрее реализовать решение задачи.
A. Искандер и рисунки
Шаг 1Рассмори одну полоску длины $$$k$$$ из символов '#'. Сколько времени нужно, чтобы ее стереть? Что происходит за одну секунду?
Шаг 2За одну секунду мы стираем 2 символа '#' (или 1, если был всего один символ). Тогда через сколько времени мы все сотрем?
Шаг 3Через $$$\lceil\frac{k}{2}\rceil$$$ секунд. Тогда чему равен ответ?
Шаг 4Мы должны найти самую длинную полоску из подряд идущих символов '#' и вычислить ответ по формуле из предыдущего шага.
Решение: 382817545
B. Никита и книги
Шаг 1В условии написано, что мы можем перекладывать единицы слева направо, тогда что логичнее всего можно сделать?
Шаг 2Логичнее всего строить последовательность слева направо. Пойдем слева направо. Пусть мы стоим в позиции $$$i$$$, тогда какую оптимальную высоту мы хотим получить здесь?
Шаг 3Какое ограничение снизу на $$$a_i$$$ мы можем записать?
Шаг 4Запишем последовательность $$$(1,2,\ldots, n)$$$ -- это возрастающая последовательность с минимальными выстоами башен, тогда $$$a_i \ge i$$$, то есть мы хотим сделать $$$a_i$$$ равным $$$i$$$.
Шаг 5Тогда будем поддерживать количество единиц $$$S$$$, которые мы можем перенести с башен до $$$i$$$-й. Что делаем, если $$$a_i \gt i$$$?
Шаг 6Если $$$a_i \gt i$$$, тогда мы можем увеличить $$$S$$$ на $$$(a_i - i)$$$ и пойти дальше (и уменьшить $$$a_i$$$ до $$$i$$$). А что если $$$a_i \lt i$$$?
Шаг 7Тогда нам нужно увелчить высоту башни, потратив $$$(i - a_i)$$$. Тогда если $$$S \lt (i - a_i)$$$, то ответа нет, а иначе уменьшаем $$$S$$$ на $$$(i - a_i)$$$ и идем дальше.
Решение: 382818009
C. Стёпа и перестановка
Шаг 1В задачах на сортировку очень часто помогает придумать способ обменять местами какие-то две элемента $$$(i,j)$$$. Попробуем поприменять описанные в условии операции несколько раз.
Шаг 2Мы можем обменивать $$$(i, i + x)$$$ и $$$(i, i + y)$$$, тогда какие два элемента мы еще можем обменять?
Шаг 3Тогда мы можем обменять $$$(i, i + x)$$$, дальше обменять $$$(i, i + y)$$$, а затем опять $$$(i, i + x)$$$, тогда мы по сути обменяли местами $$$(i + x, i + y)$$$ или другими словами $$$(i, i + (x - y))$$$. На что это похоже?
Шаг 4Как работает простейший алгоритм Евклида?
Шаг 5Алгоритм Евклида гласит, что $$$gcd(x, y) = gcd(x, y - x) = \ldots$$$. А если хотите больше узнать о нетривиальных применениях этого алгоритма, рекомендую прочитать ЭТОТ ПОСТ и присоединиться к нам в сообщество)
Шаг 6Из шагов выше получаем, что мы можем обменять местами любые два индекса $$$(i,j)$$$, что $$$|i - j|$$$ делится на $$$gcd(x, y)$$$. Как нам это помогает?
Шаг 7Это значит, что мы можем отсортировать подпоследовательности $$$i_1 \lt i_2 \lt \ldots$$$, которые имеют одинаковые остаток от деления на $$$gcd(x, y)$$$. Сдеаем это и проверим, что итоговая последовательность отсортировалась.
Решение: 382818403
D. Ярослав и продуктивность
Шаг 1Решим задачу попроще: допустим мы можем изменить знак любого префикса, чему тогда равен ответ?
Шаг 2Тогда ответ равен \sum |a_i|, как его получить?
Шаг 3Если $$$a_n \lt 0$$$, то мы можем поменять знак у префикса $$$[1 \ldots n]$$$ и перейти к вычислению ответа на массиве $$$(a_1,a_2,\ldots,a_{n-1})$$$, потому дальнейшие изменения никак не повлияют на $$$a_n$$$.
Шаг 4Возвращаемся к нашей задаче. Какие элементы мы никогда не сможем изменить?
Шаг 5Пусть $$$B = \max b_j$$$ — максимальный префикс, который мы можем изменить. Тогда все элемент $$$a_i$$$, что $$$i \gt B$$$ мы не можем изменить, значит мы можем добавить к ответу их сумму и забыть про них, теперь считаем, что мы можем поменять все элементы местами. Идем дальше. Какие элементы всегда будут меняться одинаково? (то есть нельзя изменить знак одного элемента без изменения второго)
Шаг 6Пусть $$$b_1 \lt b_2 \lt \ldots \lt b_m$$$, тогда элементы $$$[1,b_1]$$$ всегда будут меняться одинаково, а еще какие?
Шаг 7Рассмотрим блоки $$$[1, b_1], [b_1+1,b_2], [b_2+1,b_3], \ldots,[b_{m-1}+1,b_m]$$$. Элементы в каждом блоке всегда будут меняться одинаково, тогда что мы можем сделать?
Шаг 8Тогда мы можем вычислить сумму элементов в каждом блоке и перейти к задаче из Шага 1, тогда как посчитать ответ?
Шаг 9Пусть $$$S_i$$$ — сумма элементов в блоке $$$[b_{i-1}+1,b_i]$$$, тогда ответ $$$\sum |S_i|$$$
Решение: 382818882
E. Маша и гирлянда
Шаг 1Давайте формально запишем, что то нас хотят в условии. Пусть $$$f_i = 1$$$, если $$$s_i = s_{i-1}$$$ и $$$f_i = 0$$$ иначе. Тогда что от нас хотят в условии? Что означает операция выбора отрезка $$$[l,r]$$$? Что при этом меняется и как?
Шаг 2Такая оперция изменяет $$$f_l$$$ с 0 на 1 и наоборот, а также меняет $$$f_{r+1}$$$ с 0 на 1 и наоборот. То есть по сути за одну операцию мы можем изменить какие-то два элемента $$$f_i,f_j$$$ (или один, если отрезок — это префикс или суффикс). Как нам это помогает?
Шаг 3Пусть к нам пришел запрос
Unable to parse markup [type=CF_MATHJAX]
. Пусть
Unable to parse markup [type=CF_MATHJAX]
. Тогда как определить ответ?
Шаг 4В таком случае минимальное количество операций равно
Unable to parse markup [type=CF_MATHJAX]
, остается сравнить его с $$$k$$$. А чтобы посчитать
Unable to parse markup [type=CF_MATHJAX]
достаточно предподсчитать префиксные суммы.
Решение: 382819665
F. Аня любит деревья!
Решение: 382820351
G. Юра и дедлайны
Решение: 382823231