Олимпиада по информатике 9–11 классы — заключительный этап ВсОШ 2025/2026: задания и ответы
Официальный комплект заключительного этапа Всероссийской олимпиады школьников по информатике для 9–11 классов (2025/2026 учебный год). Задания и решения с критериями оценивания — скачайте PDF или прорешайте онлайн по тексту ниже.
Задания — текст для прорешивания
Текст извлечён из официального PDF автоматически: формулы, таблицы и рисунки могут отображаться неточно — сверяйтесь с документом выше.
Задания — 1 день
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, первый тур Профиль «программирование», Москва, 24 марта 2026 года
Общая информация по задачам первого тура Задача 1. Распределенные системы 2. Расследование в Темерии 3. Скобки и деревья 4. Спортивная тренировка
Тип задачи стандартная стандартная интерактивная, двойной запуск стандартная
Ограничения 1 с, 1024 МБ 2 с, 1024 МБ 2 с, 1024 МБ 2 с, 1024 МБ
Необходимо считывать данные из стандартного потока ввода. Выходные данные необходимо выводить в стандартный поток вывода. Баллы за подзадачу начисляются только если все тесты этой и необходимых подзадач пройдены. Решение запускается на тестах для определенной подзадачи, если все тесты всех необходимых подзадач пройдены. В одной из задач можно получить частичные баллы за подзадачу. Для тестирования подзадачи достаточно, чтобы во всех необходимых подзадачах был получен положительный балл. Во всех подзадачах каждой задачи во время тура вам показываются баллы за подзадачу, если все тесты пройдены, либо первая ошибка и номер теста. Для некоторых подзадач может также требоваться, чтобы были пройдены все тесты из условия. Для таких подзадач указана дополнительно буква У.
Страница 1 из 13
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, первый тур Профиль «программирование», Москва, 24 марта 2026 года
Задача 1. Распределённые системы Ограничение по времени: Ограничение по памяти:
1 секунда 1024 мегабайта
В компании n серверов, пронумерованных числами от 1 до n. На i-м сервере запущены ai сервисов. Иногда серверы могут отключаться, поэтому для каждого сервера был определён резервный сервер. Для сервера с номером i резервным является сервер с номером pi . Если у i-го сервера pi = i, то это сервер повышенной надёжности, и он никогда не отключается. Для любых двух различных серверов i и j номера их резервных серверов pi и pj не совпадают. Таким образом, p — это перестановка длины n, то есть каждое число от 1 до n встречается ровно один раз среди значений p1 , . . . , pn . Процесс отключения сервера происходит следующим образом. Если сервер i отключается, то все запущенные на нём сервисы перемещаются на сервер с номером pi , а сервер i заменяется на новый сервер, на котором не запущены никакие сервисы. Номер этого сервера и номер его резервного сервера остаются без изменений. Перенос сервисов и замена сервера очень быстрый процесс, во время него не может произойти новых отключений. В компании планируется провести тестирование работоспособности системы. Для этого будут отключены не более k серверов. Отключения проводятся последовательно, то есть никакие два сервера не отключаются одновременно. Определите максимальное число сервисов, которые могут оказаться на одном сервере после отключения не более k серверов.
Формат входных данных В первой строке заданы два целых числа n и k (1 ⩽ k < n ⩽ 105 ) — количество серверов, а также максимальное количество серверов, которые могут отключиться. Во второй строке заданы n целых чисел a1 , a2 , . . . , an (0 ⩽ ai ⩽ 109 ) — количество сервисов, запущенных на серверах. В третьей строке заданы n целых чисел p1 , p2 , . . . , pn (1 ⩽ pi ⩽ n) — номера резервных серверов.
Формат выходных данных Выведите одно целое число — ответ на задачу.
Система оценивания Подзадача
Баллы
Дополнительные ограничения
Необх. подзадачи
дополнительно
15
n ⩽ 1000
k=1
27
n ⩽ 1000
У, 1
21
pi = i mod n + 1
37
У, 1, 2, 3
Примеры стандартный ввод
стандартный вывод
4 2 6 10 7 9 2 3 4 1
26
3 1 1000000000 993 2010 1 3 2
1000000000
11 5 3 5 12 7 5 9 2 6 0 9 4 2 8 9 6 5 11 3 1 10 7 4
23
Страница 2 из 13
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, первый тур Профиль «программирование», Москва, 24 марта 2026 года
Замечание Рассмотрим порядок отключений серверов, который позволяет достичь максимальный ответ в первом примере. Напомним, как осуществляются переносы сервисов при отключении серверов. Сервер
Резерв
Первым отключается второй сервер, его сервисы переходят на третий сервер, то есть теперь на третьем сервере 10 + 7 = 17 сервисов. Вторым отключается третий сервер, его сервисы переходят на четвёртый сервер, после этого на четвёртом сервере 9 + 17 = 26 сервисов. Для лучшего понимания смотрите таблицу, в которой записано количество сервисов на каждом из серверов в ходе процесса, описанного выше. Стадия
a1
a2
a3
a4
До первого отключения
10
После отключения сервера 2
17
После отключения сервера 3
26
Если бы первым отключился третий сервер, а вторым — второй, то процесс выглядел бы так. Стадия
a1
a2
a3
a4
До первого отключения
10
После отключения сервера 3
10
16
После отключения сервера 2
10
16
При этом максимальное количество сервисов на сервере было бы равно 16, что не является оптимальным ответом. Во втором примере один из возможных вариантов — ни один сервер не отключится. Тогда на первом сервере 1000000000 сервисов, что и является ответом на задачу. Если отключится сервер 2 или 3, то максимальное число сервисов также будет на первом сервере.
Страница 3 из 13
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, первый тур Профиль «программирование», Москва, 24 марта 2026 года
Задача 2. Расследование в Темерии Ограничение по времени: Ограничение по памяти:
2 секунды 1024 мегабайта
Темерия — одно из самых могущественных королевств Севера со столицей в городе Вызима. Чародейка Трисс, которая живет в городе Вызима, обнаружила сильные магические аномалии и решила исследовать королевство Темерия, чтобы найти их источник. В Темерии располагаются n городов, пронумерованных числами от 1 до n, столица Вызима имеет номер 1. Города соединены n − 1 двусторонними дорогами, i-я дорога соединяет города с номерами ui и vi и имеет длину wi . Гарантируется, что Трисс может добраться из любого города в любой другой, пользуясь только этими дорогами. Трисс планирует начать и закончить свой путь в Вызиме, побывав во всех n городах. Трисс может ходить по дорогам, но это медленно. У неё есть k кристаллов телепортации, которыми она может воспользоваться для мгновенного перемещения между городами. В любой момент Трисс может оставить кристалл в городе, где она находится. В дальнейшем чародейка может воспользоваться ранее оставленным кристаллом и мгновенно вернуться по кратчайшему пути в город, в котором она ранее оставила кристалл. После использования кристалл разрушается. Трисс может оставлять и использовать кристаллы в произвольном порядке. К сожалению, телепортация не проходит бесследно. А именно, если Трисс, находясь в городе a, воспользовалась кристаллом и попала в город b, то во всех городах, лежащих на кратчайшем пути от a до b, включая a и b, остается магический след и в дальнейшем через такие города другой маршрут телепортации проходить не может. Помогите Трисс. Для каждого j от 1 до k включительно, определите, какое минимальное расстояние надо пройти чародейке, чтобы обойти все города королевства и вернуться в Вызиму, потратив при этом не более чем j кристаллов.
Формат входных данных В первой строке ввода находятся два целых числа n и k (2 ⩽ n ⩽ 500 000; 1 ⩽ k ⩽ n) — количество городов и количество кристаллов телепортации, которые есть у Трисс. В следующих (n − 1) строках находятся описания дорог: целые числа ui , vi и wi (1 ⩽ ui , vi ⩽ n; 1 ⩽ wi ⩽ 109 ) — номера городов, соединенных i-й дорогой, и длина этой дороги, соответственно.
Формат выходных данных Выведите k чисел, где j-е число — минимальное расстояние, которое требуется пройти чародейке, чтобы побывать во всех городах и вернуться в Вызиму, потратив не более j кристаллов.
Страница 4 из 13
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, первый тур Профиль «программирование», Москва, 24 марта 2026 года
Система оценивания Дополнительные ограничения
Подзадача
Баллы
n ⩽ 150 000; k = 1
n ⩽ 100
10
n ⩽ 5 000
У, 2
n ⩽ 150 000; k ⩽ 300
У, 1 – 2
11
n ⩽ 150 000
Полное двоичное дерево∗ , wi = 1
11
n ⩽ 150 000
wi = 1
15
n ⩽ 150 000
Специальный граф∗∗
12
n ⩽ 150 000
Из каждого города выходят не более 10 дорог
11
n ⩽ 150 000
У, 1 – 8
10
n ⩽ 300 000
У, 1 – 9
11
n ⩽ 500 000
У, 1 – 10
Дополнительно
n, k
Необх. подзадачи
∗ Полное двоичное дерево в подзадаче 5 — это дерево, состоящее из 2s − 1 вершин (n = 2s − 1), в
котором для каждого i от 1 до 2s−1 − 1 существует пара рёбер (i, 2i) и (i, 2i + 1). ∗∗ Специальный граф в подзадаче 7 — это дерево, состоящее из нечётного числа вершин n, в котором для каждого i от 1 до n−1 2 существует пара рёбер (1, 2i) и (2i, 2i + 1). 1
Примеры стандартный ввод
стандартный вывод
5 1 1 2 1 1 3 1 3 4 1 3 5 1
10 2 1 2 10 2 3 6 3 4 8 4 6 5 6 10 7 4 8 6 3 7 6 1 5 4 1 9 9
86 85
Страница 5 из 13
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, первый тур Профиль «программирование», Москва, 24 марта 2026 года
Замечание В первом примере оптимальный маршрут для Трисс выглядит следующим образом. • Трисс оставляет кристалл в городе 1, затем следует по маршруту 1 → 2 → 1 → 3 → 4 → 3 → 5, после чего используется кристалл, и она мгновенно возвращается в город 1. Во втором примере оптимальные маршруты выглядят так: • Трисс следует по маршруту 1 → 5 → 1, после чего оставляет кристалл в городе 1, затем следует по маршруту 1 → 9 → 1 → 2 → 3 → 7 → 3 → 4 → 8 → 4 → 6 → 10 и использует кристалл в городе 1. Длина такого маршрута равна 86, причём Трисс использует ровно один кристалл. В другом маршруте Трисс потребуется использовать два кристалла, обозначим их x и y. • Трисс оставляет кристалл x в городе 1; • Затем следует по маршруту 1 → 5 → 1 → 9 → 1 → 2 → 3 → 7 → 3 → 4 → 6; • В городе 6 Трисс оставляет кристалл y; • Затем переходит 6 → 10 и использует кристалл y, возвращаясь в город 6; • Идет по маршруту 6 → 4 → 8; • И заканчивает свой путь использованием кристалла x.
Страница 6 из 13
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, первый тур Профиль «программирование», Москва, 24 марта 2026 года
Задача 3. Скобки и деревья Ограничение по времени: Ограничение по памяти:
2 секунды 1024 мегабайта
Это интерактивная задача с двойным запуском. В этой задаче рассматриваются корневые деревья без порядка на детях. Корневое дерево без порядка на детях состоит из корня, у которого может быть ноль или более детей. Каждый ребенок в свою очередь является корневым деревом без порядка на детях. При этом, как и следует из названия дерева, порядок, в котором перечисляются дети, не важен, то есть деревья, изображенные на рисунке ниже являются одним и тем же деревом без порядка на детях. Далее будем называть корневые деревья без порядка на детях просто деревьями.
Любое дерево можно закодировать в виде правильной скобочной последовательности (далее — ПСП) следующим образом: • Дерево, состоящее из одной вершины, кодируется как «()». • Пусть после удаления корня дерево распадается на поддеревья t1 , t2 , . . . , tk , где k — количество детей корня исходного дерева. Положим, что s1 , . . . , sk — строки, которые кодируют деревья t1 , . . . , tk . Тогда для любой перестановки a = [a1 , a2 , ..., ak ] чисел от 1 до k исходное дерево может быть закодировано ПСП «(sa1 sa2 . . . sak )». Обратите внимание, что одно и то же дерево может быть закодировано различными ПСП. Например, дерево, изображенное на рисунке ниже, может быть закодировано с помощью ПСП «(()(()))» или «((())())».
Вам требуется научиться кодировать произвольную последовательность деревьев u1 , . . . , un в виде одного корневого дерева w. Чтобы проверить, что ваш способ кодирования корректный, ваше решение будет запущено два раза. Первый запуск При первом запуске вашей программе на вход подаются n ПСП, каждая из которых представляет собой код si некоторого корневого дерева. В ответ ваша программа должна вывести ПСП, которая кодирует произвольное корневое дерево w. В различных подзадачах накладываются различные ограничения на количество вершин в дереве w в зависимости от суммарного количества вершин в исходных деревьях. Второй запуск На втором запуске вашей программе подаётся единственная ПСП, которая кодирует дерево w, которое ваша программа вывела при первом запуске. При этом на вход может быть подана любая Страница 7 из 13
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, первый тур Профиль «программирование», Москва, 24 марта 2026 года подходящая ПСП, которая кодирует дерево w, не обязательно та, которая была выведена вашей программой при первом запуске. В ответ ваша программа должна вывести ПСП, которые кодируют те же деревья, которые были поданы при первом запуске, в том же порядке. Для каждого дерева вы можете вывести любую кодирующую его ПСП, но порядок самих деревьев в последовательности должен быть таким же, как при первом запуске программы.
Протокол взаимодействия В начале каждого запуска ваша программа должна прочитать одно число t, равное 1 или 2 — номер запуска. Первый запуск При первом запуске необходимо обработать несколько наборов входных данных. Каждый набор подаётся на стандартный поток ввода интерактивно, то есть перед тем, как считать очередной набор, ваша программа должна вывести ответ для всех предыдущих наборов входных данных и сбросить буфер стандартного потока вывода. В первой строке каждого набора входных данных записано одно число n — количество деревьев, которое нужно закодировать. Если n равно 0, то это означает, что все наборы входных данных обработаны и программа должна завершить работу. Иначе в следующих n строках следуют описания деревьев. Каждое дерево задается одной строкой si , которая состоит из символов «(» и «)» — ПСП, которая кодирует i-е дерево описанным в условии образом. Гарантируется, что si задает корректное дерево. Для данного набора входных данных программа должна вывести ПСП, которая кодирует некоторое дерево w. После вывода дерева необходимо вывести символ конца строки и сбросить буфер потока вывода. В данной задаче работа программы жюри при первом запуске является адаптивной. Это означает, что программа жюри на первом запуске может использовать выведенные вами в предыдущих наборах входных данных текущего теста деревья w при генерации нового набора входных данных. Второй запуск На втором запуске необходимо обработать несколько наборов входных данных. Каждый из наборов входных данных задаётся строкой s. Если строка s равна «0», то вы обработали все наборы входных данных, и программа должна завершить работу. Иначе s содержит некоторую ПСП, кодирующую какое-то дерево w, которое программа построила при первом запуске. Для каждого такого дерева необходимо вывести в отдельной строке одно число n — количество декодированных деревьев. В следующей строке требуется вывести n ПСП, которые кодируют в соответствующем порядке те же деревья, что кодировали строки s1 , . . . , sn , поданные при первом запуске, в одну строку, разделяя их символом «+». Например, если нужно вывести ПСП «(())» и «(()())» в таком порядке, то вывод должен быть таким: в первой строке «2», а во второй строке «(())+(()())». После вывода числа n и вывода строки с описанием деревьев необходимо перевести строку и сбросить буфер поток вывода. В каждом из наборов данных во втором запуске вашей программе на вход может подаваться любое из деревьев, полученных при первом запуске.
Замечание Не забывайте переводить строку после каждого вывода. Обратитесь к памятке участника, чтобы узнать, как правильно сбрасывать поток вывода в интерактивных задачах.
Система оценивания Обозначим за s суммарную длину ПСП в одном наборе входных данных, а за m — размер вывода вашей программы на первом запуске для этого набора входных данных. Для каждой подзадачи определена функция f (x). Подзадача считается пройденной, если для каждого набора входных данных выполняется m ⩽ f (s), а также если все деревья были корректно восстановлены. Обозначим за ti количество вершин в i-м дереве. Тогда длина строки si равна 2ti .
Страница 8 из 13
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, первый тур Профиль «программирование», Москва, 24 марта 2026 года Также гарантируется, что сумма s по всем наборам входных данных одного теста не превосходит 106 , а количество наборов входных данных в каждом тесте не превосходит 100.
Подзадача
Баллы
f (x)
13
Дополнительные ограничения s
Дополнительно
f (x) = x + 2000
s ⩽ 200 000
При втором запуске даются ПСП, точно совпадающие с выведенными вашим решением при первом запуске.
f (x) = x + 2000
s ⩽ 200 000
t1 < t2 < . . . < tn
f (x) = x + 2000
s ⩽ 200 000
n=2
до 34
f (x) = 4 · x + 2000
s ⩽ 200 000
до 11
f (x) = x + 2000
t1 = t2 = . . . = tn > 1
до 9
f (x) = x + 2000
ti > 1
до 20
f (x) = x + 2000
Необх. подз.
5 1–6
m − 2000 Четвертая подзадча оценивается по следующей формуле. Обозначим k = max 0, s для каждого набора входных данных. Введем функцию score(k) следующим образом: k
score(k)
⩽ 1,5
34
20
10
>4
Для промежуточных значений k функция вычисляется линейно между соседними строками таблицы и округляется до ближайшего целого числа. Балл за тест равняется минимуму score(k) по всем наборам входных данных в тесте. Балл за подзадачу равняется минимуму из баллов по тестам этой подзадачи. Подзадачи 5, 6 и 7 также оцениваются по формуле. Обозначим c = max(0, m − s) для каждого набора входных данных. Введем функцию score(c) следующим образом: c
score(c), подз. 5
score(c), подз. 6
score(c), подз. 7
⩽ 30
11
20
100
14
200
2000
> 2000
Для промежуточных значений c функция вычисляется линейно между соседними строками таблицы и округляется до ближайшего целого числа. Балл за тест равняется минимуму score(c) по всем наборам входных данных в тесте. Балл за подзадачу равняется минимуму из баллов по тестам этой подзадачи.
Страница 9 из 13
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, первый тур Профиль «программирование», Москва, 24 марта 2026 года
Пример стандартный поток ввода
стандартный поток вывода первый запуск
1 3 () (()) (()()) ((()(()()))) 1 ((())()) ((((((((())))))))) 0 второй запуск 2 ((((((((()))))))))
1 (()(()))
(((()())())) 3 ()+(())+(()()) 0
Страница 10 из 13
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, первый тур Профиль «программирование», Москва, 24 марта 2026 года
Задача 4. Спортивная тренировка Ограничение по времени: Ограничение по памяти:
2 секунды 1024 мегабайта
Несколько школьников занимаются в спортивной секции. В начале тренировки в зале присутствуют n человек, а затем в течение занятия к ним по одному присоединяются еще q человек. Рост всех n + q школьников различен, пронумеруем школьников от 1 до n + q по возрастанию роста. На тренировке школьники выполняют упражнения с мячом. Школьники выстраиваются в ряд слева направо в некотором порядке. В зависимости от порядка, в котором они выстроились, некоторые пары школьников образуют допустимые пары. Пара школьников, стоящих на позициях i и j, где i < j, образует допустимую пару, если выполнено одно из двух условий: • школьник на i-й позиции является самым левым школьником из тех, которые ниже школьника на j-й позиции и стоят левее него; • школьник на j-й позиции является самым правым школьником из тех, которые ниже школьника на i-й позиции и стоят правее него. Например, если в ряд стоят школьники с номерами [6, 7, 3, 5, 1, 2], то допустимыми являются пары школьников с номерами (6, 2), (6, 7), (7, 2), (3, 2), (3, 5), (5, 2), (1, 2). У упражнения есть два уровня сложности, на каждом из которых есть свои допустимые броски. При выполнении упражнения на любом уровне сложности запрещается бросать мяч школьнику, у которого он уже был во время выполнения этого упражнения. На первом уровне сложности школьник может бросить мяч любому школьнику, с которым он образует допустимую пару и который ниже его. Например, если в ряд стоят школьники с номерами [6, 7, 3, 5, 1, 2], то школьник с номером 3 может бросить мяч только школьнику с номером 2, школьник с номером 5 — школьникам с номерами 3 и 2, школьник с номером 1 не может бросить мяч никому. На втором уровне сложности школьник может бросить мяч любому школьнику, с которым он образует допустимую пару. Например, если в ряд стоят школьники с номерами [6, 7, 3, 5, 1, 2], то школьник с номером 3 может бросить мяч школьникам с номерами 2 и 5, школьник с номером 5 — школьникам с номерами 3 и 2, школьник с номером 1 может бросить мяч школьнику с номером 2. Упражнение выполняется следующим образом. Тренер выбирает уровень сложности упражнения t. Один из школьников берёт мяч и совершает допустимый бросок. Школьник, получивший мяч, снова совершает допустимый бросок, и т.д. Броски выполняются, пока это возможно. Если допустимых бросков несколько, можно выбрать любой из них, но запрещается бросать мяч тому из школьников, у кого уже был мяч во время выполнения этого упражнения. Участники, находящиеся на тренировке, выполняют допустимые для этого уровня сложности броски таким образом, чтобы было произведено максимальное число бросков. Затем q раз к тренирующимся присоединяется еще один школьник. Он встаёт справа или слева от уже выполнявших упражнение. После этого упражнение выполняется заново на том же уровне сложности. Для начального состава участников тренировки и после добавления каждого нового школьника необходимо определить, какое максимальное количество бросков смогут сделать участники тренировки.
Формат входных данных Первая строка содержит одно целое число t (1 ⩽ t ⩽ 2) — уровень сложности упражнения. Вторая строка содержит два целых числа n и q (1 ⩽ n ⩽ 105 , 0 ⩽ q ⩽ 2 · 105 ) — начальное количество участников упражнения и количество участников, которые к нему присоединятся. Третья строка содержит n целых чисел a1 , a2 , . . . , an (1 ⩽ ai ⩽ n + q) — номера участников, первоначально стоящих в ряду в порядке слева направо. Гарантируется, что все номера различны. Следующие q строк содержат номера участников, присоединяющихся к упражнению. Очередная строка содержит символ «L» или «R» и целое число x через пробел (1 ⩽ x ⩽ n + q). Буква «L» означает, что школьник номер x встает в ряд слева, а «R» — справа. Страница 11 из 13
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, первый тур Профиль «программирование», Москва, 24 марта 2026 года Гарантируется, что после каждого добавления все номера участников различны.
Формат выходных данных В первой строке выведите одно число — ответ на задачу для исходных n участников и упражнения сложности t. В следующих q строках выведите по одному целому числу — ответ на задачу после добавления очередного из q участников и выполнения упражнения той же сложности.
Примеры стандартный ввод 1 6 2 6 7 3 5 1 2 L 8 R 4
стандартный вывод 3 3 5
2 6 2 6 7 3 5 1 2 L 8 R 4
4 4 6
1 5 4 4 3 1 6 2 R 7 L 8 R 9 L 5
3 3 4 5 4
2 5 4 9 4 6 8 2 R 1 L 7 R 5 R 3
4 4 5 7 6
Пояснение к примеру В первом примере упражнение оптимально начинать, например, участнику с номером 5. Первым броском можно отдать мяч участнику с номером 3, вторым — участнику с номером 2, третьим — с номером 1. Добавление слева участника с номером 8 не увеличивает максимальное количество бросков. А добавление справа участника с номером 4 позволяет, начиная с участника с номером 7, последовательно бросать мяч участникам с номерами 6, 4, 3, 2 и 1. Во втором примере тоже можно начать с участника с номером 5 и получить четыре допустимых броска участникам с номерами 3, 2, 7 и 6. Добавление слева участника с номером 8 не меняет максимальное количество бросков, а добавление справа участника с номером 4 позволяет, начиная, например, с номера 7, последовательно бросать мяч участникам с номерами 6, 4, 5, 3, 2 и 1.
Страница 12 из 13
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, первый тур Профиль «программирование», Москва, 24 марта 2026 года
Система оценивания Доп. ограничения n, q
дополнительно
Необх. подзадачи
n + q ⩽ 16
n, q ⩽ 100
n ⩽ 1000, q = 0
n, q ⩽ 1000
1–3
q=0
n=1
a1 = 1 Школьники добавляются в порядке возрастания номеров
Подзадача
Баллы
10
t=1
Гарантируется, что начальный набор участников, их порядок, очерёдность добавления оставшихся и сторона добавления случайны
n, q ⩽ 50 000
1–4
1–8
10
n + q ⩽ 16
11
n, q ⩽ 100
10
12
n ⩽ 1000, q = 0
13
n, q ⩽ 1000
10–12
14
q=0
12
15
n=1
a1 = 1 Школьники добавляются в порядке возрастания номеров
t=2
16
Гарантируется, что начальный набор участников, их порядок, очерёдность добавления оставшихся и сторона добавления случайны
17
n, q ⩽ 50 000
10–13
18
10–17
Страница 13 из 13
Задания — 2 день
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, второй тур Профиль «программирование», Москва, 26 марта 2026 года
Общая информация по задачам второго тура Задача 5. Обобщённые шахматы 6. Ночь, улица, фонарь, аптека 7. Марсианский рюкзак 8. Хорошие раскраски – 8
Тип задачи стандартная стандартная стандартная стандартная
Ограничения 2 с, 1024 МБ 2 с, 1024 МБ 1 с, 1024 МБ 2 с, 1024 МБ
Необходимо считывать данные из стандартного потока ввода. Выходные данные необходимо выводить в стандартный поток вывода. Баллы за подзадачу начисляются только если все тесты этой и необходимых подзадач пройдены. Решение запускается на тестах для определенной подзадачи, если все тесты всех необходимых подзадач пройдены. Во всех подзадачах каждой задачи во время тура вам показываются баллы за подзадачу, если все тесты пройдены, либо первая ошибка и номер теста. Для некоторых подзадач может также требоваться, чтобы были пройдены все тесты из условия. Для таких подзадач указана дополнительно буква У.
Страница 1 из 10
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, второй тур Профиль «программирование», Москва, 26 марта 2026 года
Задача 5. Обобщённые шахматы Ограничение по времени: Ограничение по памяти:
2 секунды 1024 мегабайта
Михаил решил научиться играть в обобщённые шахматы, для чего подготовил шахматную доску размером n × n клеток. Клетку на пересечении i-й строки и j-го столбца он раскрасил в цвет aij . Михаил начинающий игрок и мог раскрасить доску неправильно. Поэтому некоторые клетки доски, возможно, потребуется перекрасить в другой цвет. Доска считается раскрашенной правильно при выполнении двух условий: • клетки доски покрашены в не более чем два различных цвета; • на доске нет соседних по стороне клеток, раскрашенных в один и тот же цвет. Михаил задумался о том, что играть на большой доске ему будет слишком сложно. Поэтому он, возможно, выпилит из своей доски доску поменьше, оставив участок, состоящий из первых r строк и первых c столбцов, и раскрасит правильно только этот участок. Для каждой пары чисел r и c (1 ⩽ r ⩽ n, 1 ⩽ c ⩽ n) вычислите значение brc — минимальное количество клеток, которые надо перекрасить Михаилу так, чтобы прямоугольный участок доски из первых r строк и первых c столбцов был раскрашен правильно.
Формат входных данных В первой строке содержится число n (1 ⩽ n ⩽ 400) — размер доски. В следующих n строках следует описание доски: i-я из этих строк содержит n целых чисел ai1 , . . . , ain (1 ⩽ aij ⩽ 109 ) — цвета клеток, находящихся в i-й строке доски.
Формат выходных данных Выведите n строк, где i-я строка должна содержать n чисел bi1 , . . . , bin .
Система оценивания Доп. ограничения n
aij
Необх. подзадачи
11
n ⩽ 50
22
n ⩽ 200
У, 1
aij ⩽ 2
17
aij ⩽ 10
У, 3
15
aij ⩽ 100
У, 3–4
aij ⩽ 104
У, 3–5
20
У, 1–6
Подзадача
Баллы
Примеры стандартный ввод
стандартный вывод
2 7 7 7 7
0 1 1 2
3 1 1 2 2 4 4 3 1 2
0 1 1 0 2 4 1 3 5
Страница 2 из 10
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, второй тур Профиль «программирование», Москва, 26 марта 2026 года
Задача 6. Ночь, улица, фонарь, аптека Ограничение по времени: Ограничение по памяти:
2 секунды 1024 мегабайта
Вдоль длинной улицы стоят фонарные столбы, на которых расположены n фонарей. Введём систему координат вдоль улицы. Столб, на котором размещён i-й фонарь, находится в точке с координатой xi . В первых шести подзадачах данной задачи, оценивающихся в 85 баллов, никакие два фонаря не прикреплены к одному и тому же столбу, то есть все значения xi различны. В последних двух подзадачах на каждом столбе может быть не более двух фонарей. Для освещения улицы можно включить некоторые фонари. Включённый фонарь с номером i имеет яркость si . Он светит таким образом, что освещает непрерывный участок улицы длиной si метров от столба, на котором он находится. Каждый включённый фонарь можно повернуть либо налево, либо направо. Если направить i-й фонарь налево, он освещает отрезок улицы [xi − si , xi ], а если направо, то [xi , xi + si ]. Выберем непустое множество фонарей, которые будут включены для освещения участка улицы. Будем называть это множество фонарей экономным, если можно направить каждый выбранный фонарь налево или направо таким образом, чтобы выполнялись два условия: • освещённые отрезки формируют непрерывный отрезок улицы; • никакой отрезок ненулевой длины не освещён двумя или более фонарями одновременно. На рисунке ниже показаны экономные подмножества из двух фонарей для второго примера из условия и способы осветить непрерывный участок улицы. Над каждым фонарем написана его яркость. 1
Найдите количество экономных подмножеств фонарей. В качестве ответа выведите остаток от деления полученной величины на 109 + 7.
Формат входных данных В первой строке находится единственное число n (1 ⩽ n ⩽ 105 ) — количество фонарей. Далее идёт описание фонарей. В каждой из следующих n строк находятся два целых числа xi и si — координата столба, на котором расположен i-й фонарь и его яркость (1 ⩽ xi ⩽ 5 · 105 , 1 ⩽ si ⩽ 5 · 105 , x1 ⩽ x2 ⩽ . . . ⩽ xn ). Гарантируется, что не более двух фонарей расположены на одном и том же столбе, то есть для каждого v существует не более двух значений i, таких что xi = v.
Формат выходных данных Выведите единственное целое число — остаток от деления на 109 +7 количества способов выбрать экономное подмножество фонарей.
Страница 3 из 10
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, второй тур Профиль «программирование», Москва, 26 марта 2026 года
Система оценивания Введем переменную t — максимальное количество фонарей, которые могут иметь одну и ту же координату xi . Если t = 1, то x1 < x2 < . . . < xn . Если t = 2, то x1 ⩽ x2 ⩽ . . . ⩽ xn , причем если xi = xi+1 , то xi−1 < xi и xi+1 < xi+2 (если соответствующие фонари существуют).
Подзадача
Баллы
Дополнительные ограничения дополнительно
10
t=1
n ⩽ 10
15
t=1
Для любых двух различных фонарей i, j выполняется xi − si ̸= xj и xi + si ̸= xj − sj
15
t=1
Для любых двух различных фонарей i, j выполняется si ̸= sj .
15
t=1
Для любых двух различных фонарей i, j выполняется si = sj .
10
t=1
20
t=1
10
t=2
t=2
n ⩽ 1000
Необх. подзадачи
si , xi ⩽ 1000 1–5 Eсли xi = xi+1 , то si ̸= si+1 .
1–6 У, 1 – 7
Страница 4 из 10
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, второй тур Профиль «программирование», Москва, 26 марта 2026 года
Примеры стандартный ввод
стандартный вывод
2 2 3 7 2
3 1 1 3 1 4 2
5 3 2 4 2 5 2 6 2 7 2
10
4 3 2 7 4 7 4 8 2
5 1 2 1 3 2 1 2 2 4 1
19
Замечание В первом примере все три непустых подмножества фонарей являются корректными. Во втором примере корректными являются все подмножества фонарей, кроме множества {1, 2, 3}.
Страница 5 из 10
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, второй тур Профиль «программирование», Москва, 26 марта 2026 года
Задача 7. Марсианский рюкзак Ограничение по времени: Ограничение по памяти:
1 секунда 1024 мегабайта
Марсианин Марвин собирает рюкзак. Перед ним лежат n предметов, пронумерованных числами от 1 до n. Каждый предмет имеет две характеристики: i-й предмет обладает странностью wi и стоимостью ci . Странность предмета является неотрицательным целым числом, двоичная запись которого содержит не более k бит (0 ⩽ wi < 2k ), стоимость предмета является неотрицательным целым числом, не превышающим 109 (0 ⩽ ci ⩽ 109 ). Общая стоимость набора предметов равна сумме стоимостей входящих в него предметов, а общая странность этого набора определяется как побитовая операция «ИЛИ» странностей входящих в него предметов. Марвин называет набор предметов ценным, если его общая стоимость не меньше C. Для всех i от 1 до n Марвин хочет выбрать из предметов с номерами, не превосходящими i, ценный набор предметов такой, чтобы его общая странность была как можно меньше. Побитовое «ИЛИ» набора целых чисел определяется следующим образом: рассмотрим двоичные записи этих чисел. Тогда i-й бит результата равен 1, если хотя бы у одного из чисел набора i-й бит равен 1. В языках программирования эта операция обозначается знаком «|». Например, (10 | 3 | 9) = (10102 | 00112 | 10012 ) = 10112 = 11.
Формат входных данных Первая строка содержит три целых числа n, k и C (1 ⩽ n ⩽ 2 000 000, 1 ⩽ k ⩽ 22, 1 ⩽ C ⩽ 1015 ) — количество предметов, ограничение на длину битового представления странности и минимальная стоимость ценного подмножества. В следующих n строках записаны по два целых числа wi и ci (0 ⩽ wi < 2k , 0 ⩽ ci ⩽ 109 ) — странность и стоимость очередного предмета, соответственно.
Формат выходных данных Выведите n чисел, i-е число должно быть равно минимальной общей странности ценного подмножества первых i предметов. Если выбрать ценное подмножество невозможно, выведите −1.
Система оценивания Доп. ограничения n
дополнительно
Необх. подзадачи
10
n ⩽ 20
k ⩽ 10
11
n ⩽ 100
k ⩽ 10
У, 1
14
n ⩽ 50000
k ⩽ 10
У, 1 – 2
13
n ⩽ 1 000 000
k ⩽ 19
Все wi являются степенью двойки
11
n ⩽ 2000
У, 1 – 2
18
n ⩽ 500 000
k ⩽ 16
У, 1 – 3
n ⩽ 1 000 000
k ⩽ 19
У, 1 – 4, 6
k ⩽ 19
У, 1 – 4, 6 – 7
11
У, 1 – 8
Подзадача
Баллы
Страница 6 из 10
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, второй тур Профиль «программирование», Москва, 26 марта 2026 года
Пример стандартный ввод 5 4 12 8 7 2 6 3 6 1 12 3 5
стандартный вывод -1 10 3 1 1
Замечание Для i = 1 есть один предмет со странностью 8 и стоимостью 7. Поскольку нельзя выбрать подмножество одного предмета, чтобы сумма стоимостей была хотя бы 12, ответ равен −1. Для i = 2 есть два предмета, и единственный вариант выбрать ценное подмножество — это взять оба предмета. Общая странность будет равна 8 | 2 = 10. Для i = 3 ценным будет любое подмножество из двух или более предметов. Оптимальным будет выбрать второй и третий предметы, их общая странность будет 2 | 3 = 3. Для i = 4 становится возможным выбрать только четвертый предмет, стоимость которого достаточна, а странность равна 1, что является минимально возможным. Для i = 5 также оптимально будет выбрать только четвертый предмет.
Страница 7 из 10
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, второй тур Профиль «программирование», Москва, 26 марта 2026 года
Задача 8. Хорошие раскраски — 8 Ограничение по времени: Ограничение по памяти:
2 секунды 1024 мегабайта
Ильдар решил заняться абстрактным искусством. В качестве основы для картины он взял корневое дерево с n вершинами: граф без циклов, у которого вершина номер 1 объявлена корнем. У корня нет родителя, а для любой другой вершины u ⩾ 2 первая вершина на пути от u до корня называется родителем вершины u, обозначим её как pu . Вершины, родителем которых является вершина v, называются детьми вершины v. Если у вершины нет детей, она называется листом. Гарантируется, что у корня есть хотя бы два ребёнка. Выполним обход в глубину дерева: посетим корень, а затем по очереди рекурсивно посетим поддеревья его детей тем же способом. Вершины дерева пронумерованы в порядке этого обхода в глубину. Таким образом, для каждого i от 1 до n номера вершин из поддерева вершины i образуют набор последовательных целых чисел. Пусть в дереве m листьев. Ильдар выписал их номера в порядке возрастания, получив последовательность номеров l1 < l2 < . . . < lm , и соединил ребром все пары листьев вида (lj , lj+1 ), а также соединил ребром вершины lm и l1 . Добавленный в граф цикл l1 → l2 → . . . → lm → l1 назовём внешним циклом. Полученный граф Ильдар нарисовал на плоскости следующим образом: внешний цикл он изобразил в виде окружности, вдоль которой против часовой стрелки располагаются листья l1 , l2 , . . . , lm , дуги окружности между соседними вершинами изображают рёбра внешнего цикла. Остальные вершины дерева изображены в виде различных точек, которые находятся внутри этой окружности. Рёбра дерева изображаются отрезками между вершинами, причем вершины и рёбра расположены таким образом, что отрезки рёбер не имеют общих внутренних точек. Рисунок ниже показывает пример изображения дерева. 6
5 1
На рисунке Ильдара часть плоскости внутри окружности внешнего цикла разделилась на m областей, ограниченных рёбрами графа. Будем называть эти области гранями. Будем называть различные грани соседними, если они имеют общее ребро. Например, на рисунке выше получается 5 граней, обозначим их как Γ1 , Γ2 , Γ3 , Γ4 и Γ5 . 6
Γ3 7
Γ2
Γ4
1 8
Γ1
Γ5
Страница 8 из 10
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, второй тур Профиль «программирование», Москва, 26 марта 2026 года Соседними на рисунке выше являются пары граней (Γ1 , Γ2 ), (Γ1 , Γ5 ), (Γ2 , Γ3 ), (Γ2 , Γ4 ), (Γ2 , Γ5 ), (Γ3 , Γ4 ) и (Γ4 , Γ5 ). Для завершения своей картины Ильдар планирует раскрасить каждую грань в один из k цветов. Раскраска называется корректной, если соседние грани раскрашены в различные цвета. Ильдар называет потенциалом своего рисунка остаток от деления количества различных корректных раскрасок на число 109 + 7. Оценив потенциал исходного рисунка, Ильдар q раз выполняет операции с рёбрами изображённого графа. Рассмотрим i-ю операцию, она задаётся числом vi и выполняется с ребром дерева, соединяющим вершины vi и pvi . Если это ребро в настоящий момент изображено на рисунке, то Ильдар удаляет с рисунка данное ребро, а если это ребро отсутствует на рисунке, то оно снова изображается. После каждого изменения множество граней на рисунке может поменяться: две грани могут объединиться при удалении ребра или одна грань может разбиться на две при изображении. Например, если на рисунке выше удалить ребро 8 − 9, то грани Γ4 и Γ5 объединятся в одну грань Γ4+5 . 6
Γ3 7
Γ2
Γ4+5
Γ1
Теперь на рисунке соседними являются пары граней (Γ1 , Γ2 ), (Γ1 , Γ4+5 ), (Γ2 , Γ3 ), (Γ2 , Γ4+5 ) и (Γ3 , Γ4+5 ). После выполнения каждой операции необходимо снова определить потенциал рисунка: остаток от деления количества корректных раскрасок граней в не более чем в k цветов на 109 + 7.
Формат входных данных Первая строка входных данных содержит число t (1 ⩽ t ⩽ 10 000) — количество наборов входных данных. Далее идёт описание t наборов входных данных. В первой строке каждого набора записаны три числа n, k и q (3 ⩽ n ⩽ 106 , 2 ⩽ k ⩽ 109 , 0 ⩽ q ⩽ 300 000) — количество вершин в дереве, количество доступных цветов и количество выполненных операций, соответственно. Во второй строке каждого набора содержатся числа p2 , p3 , . . . , pn (1 ⩽ pi < i), где pi является предком вершины i в дереве. Гарантируется, что вершины дерева пронумерованы в порядке обхода в глубину и что значение 1 встречается не менее двух раз среди значений p2 , . . . , pn . Далее следуют q строк, в i-й из которых записано число vi (2 ⩽ vi ⩽ n) — параметр i-й операции. Гарантируется, что сумма значений n по всем наборам входных данных не превосходит 106 . Гарантируется, что сумма значений q по всем наборам входных данных не превосходит 300 000.
Формат выходных данных Выведите q + 1 чисел, первое из которых должно быть равно потенциалу первоначального рисунка, а остальные равны потенциалу рисунка после выполнения каждой операции.
Страница 9 из 10
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап, второй тур Профиль «программирование», Москва, 26 марта 2026 года
Система оценивания Назовём высотой дерева максимальное количество рёбер на простом пути от корня до другой вершины.
Подз.
Баллы
Доп. ограничения n
дополнительно
n=3
k⩽4
q ⩽ 10
t ⩽ 100, p2 = p3 = 1
n ⩽ 1 000
q=0
pi = 2 · ⌊ 2i ⌋ − 1, n нечетно
10
n ⩽ 1 000
q ⩽ 1 000
pi = 1
n⩽9
k⩽4
q=0
t ⩽ 100
n⩽9
k⩽4
q ⩽ 10
t ⩽ 100
n ⩽ 1 000
k=2
q=0
11
n ⩽ 1 000
15
n ⩽ 1 000
10
11
12
13
Необх. подзадачи
1 У, 4
q=0
2, 4, 6
q ⩽ 1 000
У, 1 – 7
n ⩽ 5 000
q ⩽ 5 000
У, 1 – 8
n ⩽ 10 000
У, 1 – 9
n ⩽ 100 000
У, 1 – 9
n ⩽ 100 000
высота не больше 20
У, 1, 4, 5
14
n ⩽ 100 000
У, 1 – 12
14
n ⩽ 300 000
У, 1 – 13
15
n ⩽ 1 000 000
q ⩽ 10 000 P q ⩽ 5 000 P q ⩽ 100 000 P q ⩽ 100 000 P q ⩽ 300 000 P q ⩽ 300 000
У, 1 – 14
Пример стандартный ввод 2 3 4 5 1 1 2 3 2 3 3 9 4 8 1 2 2 1 5 5 1 8 9 8 3 5 4 3 9 8
стандартный вывод 12 4 4 4 12 4 96 48 48 24 12 12 12 12 36
Страница 10 из 10
Ответы и решения — показать
Официальные ответы и критерии оценивания жюри. Сначала решите задания самостоятельно.
Решения — 1 день
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года
Задача 1. Распределённые системы Краткое условие задачи: Имеется n серверов, на i-м сервере запущено ai служб. Для каждого сервера i задан резервный сервер pi ; массив p — перестановка, и pi = i только для «надёжных» серверов, которые никогда не отключаются. Если сервер i отключается, его службы мгновенно перемещаются на pi , а сам сервер заменяется пустым (его номер и резервный сервер сохраняются). Отключения происходят последовательно, их количество не превышает k. Нужно определить максимальное возможное число служб, которые могут оказаться одновременно на одном сервере после отключения не более k Краткая идея решения: Поскольку p — перестановка, граф, образованный ребрами i → pi , состоит из независимых ориентированных-циклов. Отключая серверы, мы «склеиваем» их со следующим по направлению ребра, так что после отключения не более k серверов все службы могут оказаться на одном сервере только из последовательных (по направлению цикла) максимум k + 1 серверов. Следовательно, ответ равен максимальной сумме ai по любому (циклическому) подотрезку длины L = min|C|, k + 1, где |C| — длина рассматриваемого цикла. Для каждого цикла считаем максимум суммы L последовательных элементов (все ai ⩾ 0, поэтому более короткий отрезок не даёт большего результата). Это делается скользящим окном за O(|C|). Суммируя время выполнения по всем циклам получаем решение за O(n) времени и O(n) памяти. Подробный разбор: Подзадача 1 (k = 1) При отключении одного сервера i его службы переходят на pi . Если pi = i (надёжный сервер), то его нагрузка останется равной ai независимо от отключения. Если pi ̸= i, то после отключения i на сервере pi будет api + ai служб. Мы можем также решить не отключать ни одного сервера, тогда нагрузка остаётся aj на каждом сервере j. Алгоритм: • Инициализировать ответ ans = maxj aj (случай без отключений). • Для каждого i с pi ̸= i обновить ans = max(ans, ai + api ). Сложность — O(n) времени, O(1) памяти. Подзадача 2 (n ⩽ 1000) Теперь k может быть произвольным, но n маленькое, поэтому сложность может быть не оптимальной. Поскольку граф — набор независимых ориентированных-циклов. Отключения в разных циклах не влияют друг на друга, потому что службы никогда переходят из одного цикла в другой. Поэтому задачу можно решить по отдельности для каждого цикла и взять максимум. Организуем перебор внутри цикла. Пусть цикл содержит m серверов. Запишем их количества служб в массив b[0 . . . m − 1] в порядке следования по ребрам i → pi . После отключения t (0 ⩽ t ⩽ k) серверов, расположенных подряд, их службы соберутся на следующем сервере, т.е. там окажется сумма на отрезке длины t + 1. Следовательно, ответ для данного цикла — максимальная сумма элементов на циклическом подотрезке длиной не более k + 1. Будем перебирать начала всех подотрезков. Для каждого начала l (от 0 до m − 1) перебираем len = 1 . . . min(m, k + 1) и считаем сумму b[l] + b[l + 1] + . . . + b[l + len − 1] (индексы берём по модулю mm). Сохраняем глобальный P максимум. Суммарная сложность O( (|C|2 )) ⩽ O(n2 ) что укладывается в ограничение. Подзадача 3 (pi = i mod n + 1) , один цикл) Задан один цикл длины n. Нужно найти максимум суммы на циклическом подотрезке длиной не более L, где L = min(n, k + 1). Так как ai ⩾ 0, удлинение подотрезка никогда не уменьшает сумму. Поэтому оптимальный подотрезок будет самой большой возможной длины L
Страница 1
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года Реализуем алгоритм скользящего окна. Сформируем массив b длиной 2n, копируя исходный массив a дважды подряд PL−1(это позволяет пройти по циклу без модулей). Вычислим сумму первых L элементов: cur = i=0 b[i]. Инициализируем ans = cur. Для i от 1 до n − 1 реализуем сдвиг окна cur = cur − b[i − 1] + b[i + L − 1] (сдвиг окна на один вправо). На кажодм шаге выбираем ans = max(ans, cur). Сложность — O(n) времени, O(n) памяти (можно и O(1), если использовать кольцевой буфер). Полное решение Разложим граф на циклы. Создадим массив used[1..n], в котором будет храниться, посещен ли узел или нет. Будем идти по ребрам пока не вернёмся к уже посещённому узлу, собирая все вершины в текущий цикл. Для найденного цикла определим максимальную сумму как в предыдущей подзадаче. Суммарная длина циклов равна n, таким образом сложность правильного решения равна O(n).
Задача 2. Расследование в Темерии Краткое условие Дано дерево с n вершинами, корень — вершина 1, ребро i имеет длину wi . Трисс должна начать и закончить путь в корне, посетив все вершины. У неё есть не более k кристаллов телепортации. В любой момент она может оставить кристалл в текущей вершине и позже мгновенно переместиться к любой вершине, где уже был оставлен кристалл, проходя по единственному пути между ними. После использования кристалла все вершины этого пути «запятнаны» и больше не могут участвовать в телепортах. Для каждого j = 1 . . . k найдите минимальное пройденное расстояние, если можно использовать не более j кристаллов.
Замечание Заметим, что эффективно телепортироваться только по вертикальным путям (то есть из вершины v телепортироваться в какого-то своего предка). Тогда задача сводится к тому, чтобы найти набор из максимальных по весу k вершинно-непересекающихся путей.
Подзадача 1: n ⩽ 150 000; k = 1 В этой подзадаче достаточно было найти самый большой вертикальный путь — его величина равна высоте дерева.
Подзадачи 2–4: n ⩽ 5 000 или n ⩽ 150 000; k ⩽ 300 Воспользуемся методом динамического программирования: вычислим значения dp[v][s] — максимальная суммарная стоимость s непересекающихся по вершинам путей в поддереве v. Так как все веса положительны, то это означает, что в таком разбиении всегда будет путь, начинающийся в вершине v, потому что можно взять путь, начинающийся в ближайшей к v вершине, и продлить его. Если вычислять данную dp[v][s] для всех v ∈ [1, n] и для всех s ∈ [0, k], то наивно можно оценить вычисление этой ДП временем работы O(nk 2 ). Но эта ДП — частный случай рюкзаков на дереве, а поэтому, если дополнительно ограничить измерение s размером поддерева v сверху, это позволяет получить лучшую оценку на время работы. 2 Одной из самых известных оценок наP время Q работы такой ДП является O(n ). Действительно, время работы можно оценить как сумму v u1 ̸=u2 sz(u1 )sz(u2 ), где суммирование ведется по всем вершинам v, а u1 и u2 — непосредственные потомки вершины v, и sz(w) обозначает количество вершин в поддереве w. С одной стороны, эта сумма подсчитывает суммарное количество пар вершин, находящихся в различных поддеревьях относительно какой-то вершины v, а с другой стороны, каждая пара вершин входит в эту сумму не более одного раза, откуда и следует искомая оценка. Страница 2
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года Менее известной является оценка времени работы O(nk). Ее можно получить, если отдельно оценить сверху объединения пар двух ДП из поддеревьев размером больше k, объединение всех пар поддеревьев не больше k и, наконец, объединение пар поддеревьев, где одно поддерево не больше k, а другое — больше k.
Подзадачи 5–6: n ⩽ 150 000, wi = 1 Если wi = 1, то работает жадный алгоритм — достаточно каждый раз выбирать самый длинный путь, который остался в дереве, и добавлять его в ответ. Такой алгоритм можно эффективно реализовать следующим образом: • Для каждого поддерева v явно вычислим его высоту h(v); • Проведем тяжелое ребро из вершины v в самое высокое поддерево этой вершины. Если таких деревьев несколько, то проведем тяжелое ребро в одно из этих поддеревьев; • В конце мы получили явное разбиение дерева на тяжелые пути, и ясно, что существует вариант исполнения жадного алгоритма, когда будут выбраны именно такие пути. • Остается только выделить эти пути, отсортировать их по убыванию их длины и насчитать префиксные суммы на массиве их длин — это и будет искомый ответ на задачу.
Подзадача 7: n ⩽ 150 000, специальный граф Пусть у вершины 1 есть m детей, которые состоят из ребер с весами xi и yi в порядке сверху-вниз. То есть ребро xi из i-го пути инцидентно корню дерева, а ребро с весом yi инцидентно листу из i-го пути. Тогда ясно, что ответ выглядит как: ( ) X ans(k) = max max xi + yi B⊂1,2,...,m,|B|=k
i∈B
i∈B
Это так, потому что, если нам надо выделить k путей, то надо сначала выбрать, в каких поддеревьях будут находиться эти пути, и ровно один из этих путей сможет быть продлен до корневой вершины. Чтобы найти искомую стоимость разбиения на k, отсортируем все пары (xi , yi ) по возрастанию xi . В ходе алгоритма мы эти пары разделим на два типа: те пары, где xi выступает максимумом в каком-то оптимальном выборе, и где xi никогда не становится максимальным. Заметим, что задачу можно решить жадно, добавляя пути по одному. Пути можно добавлять по одному, для этого достаточно рассматривать либо пару, где максимален xi , либо путь, в котором максимально значение xi + yi (с предположением, что максимум увеличится). Это можно сделать, заранее отсортировав массив двумя способами, и выбирать очередной максимум. Если какой-то элемент не подходит под жадное изменение, то его можно просто игнорировать.
Общие замечания про жадные алгоритмы. В этой задаче в общем случае работает жадный алгоритм, который является комбинацией идей из подгрупп 6 и 7. Можно добавлять пути по очереди двумя способами: • Очередной путь добавляется по еще не задействованным вершинам в других путях; • Очередной путь проходит по одной задействованной вершине и идет вниз по незадействованным вершинам. При этом одно ранее добавленное ребро удаляется. Доказать этот жадный алгоритм можно с помощью MCMF (mincost maxflow): раздвоим каждую вершину дерева i на две вершины ui и vi и добавим две фиктивные вершины s и t, ребра устроены следующим образом:
Страница 3
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года • Есть ребра из s в ui для всех i с нулевой стоимостью; • Есть ребра из vi в t для всех i с нулевой стоимостью; • Есть ребра из ui в vi для всех i с нулевой стоимостью; • Для каждого вертикального ребра j = pi есть ребро в сети из vj в ui со стоимостью веса исходного ребра дерева. Все пропускные способности равны единице. Если наивно рассмотреть всевозможные увеличивающие цепочки в этой сети (с требованием на простоту пути в остаточной сети), то как раз и получится два жадных способа увеличения количества путей.
Подзадачи 8–11. n ⩽ 500 000 С помощью структур данных (например, дерево отрезков в комбинации с эйлеровым обходом дерева)можно жадно поддерживать стоимость добавления пути первым и вторым способом (описанных в подгруппе ранее). При этом суммарная длина путей не будет превосходить n + k по очевидным причинам, поэтому каждое добавленное ребро можно учитывать отдельно. Другой подход заключается в том, чтобы объединить решение подзадач 6–7 и совместить жадный алгоритм с динамическим программированием. Для каждой вершины будем поддерживать массив изменений суммарной стоимости путей, если количество путей увеличивать на один. Чтобы объединить ДП, достаточно просто объединить все изменения, идущие после первого добавленного пути. А чтобы понять, какие первые добавленные пути в каждом поддереве вершины v, требуется игнорировать дальнейшие изменения и воспользоваться подзадачей 7.
Задача 3. Скобки и деревья Краткое условие задачи В первом запуске интерактивной программы подается n правильных скобочных последовательностей s1 , . . . , sn — коды неупорядоченных корневых деревьев. Нужно вывести одну ПСП w, кодирующую некоторое дерево, из которого во втором запуске (получив любую ПСП, кодирующую то же дерево) можно восстановить исходные s1 , . . . , sn в том же порядке. Ограничения — длина w должна P быть O( |si |), конкретные ограничения на длину указаны в подгруппах.
Подгруппы 1–2: f (x) = x + 2000, S ⩽ 200 000, При втором запуске даются ПСП, точно совпадающие с выведенными при первом запуске или t1 < t2 < . . . < tn В этих подгруппах можно закодировать данные строки s1 , . . . , sn как «(s1 . . . sn )». Этот способ не работает в общем случае, поскольку, хотя порядок детей в деревьях неважен, нам нужно будет восстановить порядок самих деревьев. Во второй подгруппе размеры деревьев строго возрастают, поэтому мы можем восстановить исходный порядок, отсортировав по возрастанию длины строки s′1 , . . . , s′n из полученной ПСП «(s′1 . . . s′n )». Реализация этих групп может работать только со строками, то есть не строить деревья из ПСП.
Подгруппа 3: f (x) = x + 2000, S ⩽ 200 000, n = 2 В этой подгруппе нам нужно передать единственный бит информации, отвечающий за порядок двух деревьев. Это можно сделать, например, за m = s + 8, таким образом: • если |s1 | ⩽ |s2 |, выведем «((s1 )(s2 ))»; • если |s1 | > |s2 |, выведем «((s1 )(s2 )())». s1 и s2 можно получить как два поддерева на глубине 2, а их порядок восстанавливается в зависимости от количества детей у корня. Страница 4
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года
Подгруппа 4: f (x) = 4 · x + 2000, S ⩽ 200 000, n = 2 В этой подгруппе в силу неточных ограничений возможны многие решения. Наиболее простые из них используют авторскую идею: построим бамбук высоты n и будем подвешивать i-е дерево к его вершине на высоте i (возможно, через какие-то дополнительные вершины). Например, решение с ПСП длины m = s + 4n + 6 может выглядеть так: ((s1 )((s2 )( . . . ((sn )(()())) . . . ))) Здесь мы подвешиваем к концу бамбука поддерево «(()())»; нам нужно отличить наш бамбук от других путей, заканчивающихся этим поддеревом. Для этого встанем в корень и каждый раз будем спускаться в вершину с двумя детьми (за вершину с одним ребёнком подвешено si ). Поскольку s ⩾ 2n, m = s + 4n + 6 ⩽ 3s + 6, причём оценка достигается только на тесте из n деревьев размера 1. Поэтому, чтобы улучшить константу при s, нужно более аккуратно работать с деревьями маленького размера. Например, если i-е дерево — бамбук, мы можем подвешивать его напрямую к бамбуку, а не через промежуточную вершину. Другое решение строит бамбук большей длины, чтобы его конец был самой глубокой вершиной в дереве; для этого достаточно n + 12 s вершин.
Подгруппа 5: f (x) = x + 2000, t1 = t2 = . . . = tn > 1 В этой подгруппе будем развивать конструкцию из предыдущей подгруппы, но избавимся от дополнительного бамбука. Вместо добавления отдельных вершин расположим корни исходных деревьев в один путь. То есть подвесим корень второго дерева как ребенка корня первого дерева. Корень третьего дерева подвесим как ребенка корня второго дерева и так далее. Так как размеры всех деревьев одинаковы, то подвешенный корень всегда будет самым большим поддеревом у корня предыдущего дерева. Заметим, что тогда в случае, если исходно было больше одного дерева, то можно легко восстановить все деревья — у корня возьмем все поддеревья, кроме самого большого по размеру, это дает нам первое дерево. Дальше спускаемся в самого глубокого ребенка, пока его размер не станет равным размеру первого дерева. Чтобы обработать случай одного дерева, подвесим получившийся путь корней деревьев к отдельной вершине. К этой вершине подвесим отдельный лист в случае, если исходное дерево было одно. Так по количеству детей корня сможем определить, было ли одно дерево или несколько.
Подгруппа 6: f (x) = x + 2000, ti > 1 Для этой подгруппы будем использовать похожую конструкцию, как в предыдущей группе, с путем из корней деревьев. Однако, если построить такой же путь из корней деревьев, то теперь не всегда у очередного корня самым большим ребенком будет корень следующего дерева. Такое может происходить, когда размер текущего дерева больше суммарного размера всех оставшихся деревьев. Назовем такие деревья тяжелыми (в том числе последнее дерево тоже является тяжелым). Заменим тяжелые деревья следующей конструкцией: Создадим отдельную вершину. К ней подвесим ребенком ещё одну вершину, а уже к ней подвесим корень тяжелого дерева. Теперь создадим путь из корней деревьев, как мы и делали в предыдущей подгруппе, и подвесим к нему в конце одну вершину. Теперь надо научиться декодировать тяжелые деревья. Заметим, что, когда мы будем спускаться по пути корней в самого тяжелого ребенка, то, когда мы окажемся в тяжелом дереве, мы спустимся в вершину с ровно одним ребенком. Так как у нас нет деревьев единичного размера, то такие вершины не могут лежать на пути из корней деревьев. Таким образом, мы сможем определять тяжелые деревья и спускаться ниже в другую ветку. Последняя вершина, которую мы отдельно подвесили к концу пути корней, будет индикатором окончания деревьев. Заметим, что тяжелых деревьев не будет много. Так как тяжелое дерево по размеру больше суммарного размера всех следующих деревьев, то каждое тяжелое дерево хотя-бы в 2 раза увеличивает суммарный размер всех деревьев. Поэтому количество добавленных вершин будет не более удвоенного логарифма количества деревьев. Страница 5
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года
Полное решение Альтернативный способ пометить бамбук, за который мы подвешиваем данные деревья — это подвесить за его конец случайно сгенерированный «маркер». Тогда на втором запуске можно будет найти его с помощью хеширования поддеревьев. Решения с константным маркером не работают, потому что интерактор может подавать на вход решению части деревьев, выведенных участником ранее. Один из способов обойти это — инициализировать случайный генератор некоторой характеристикой входа. Например, можно генерировать маркер фиксированного размера и инициализировать генератор размером ввода, поскольку он будет известен на обоих запусках. Решение на 100 баллов должно использовать маркер размера не больше 15, но количество корневых деревьев размера 15 (87 811) уже сравнимо с ограничениями задачи (⌊106 /30⌋ = 33 333). Поэтому возможен тест, который содержит много различных поддеревьев размера 15 и с большой вероятностью содержит сгенерированный маркер. Мы можем представить себе битовую маску длины 87 811, в которой i-й бит включён, если вход содержит i-е дерево размера 15 (например, в порядке возрастания хеша). Когда мы выбираем маркер, мы дополнительно включаем ещё один бит, который мы должны восстановить на втором запуске. Посчитаем префиксные балансы, считая, что включённые биты дают +1, а выключенные −1. В конце баланс будет отрицательным; пусть минимальный баланс впервые достигается на i-м бите. Тогда включим его (выберем в качестве маркера i-е дерево); на суффиксе баланс увеличится на 2. После этого изменения новый минимальный баланс в последний раз достигается на (i − 1)-м бите. Это нам и нужно найти на втором запуске.
Задача 4. Спортивная тренировка Решение 1 Самая важная мысль состоит в том, что после перехода к порядку по возрастанию значений сами значения больше не важны. Остаётся только строка над алфавитом {L, R, M }. Пусть текущие участники стоят в ряд, а posx — позиция участника с номером x в этом ряду. Рассмотрим участников в порядке возрастания номеров. Предположим, что все меньшие номера уже обработаны. Среди них для нас важны только две величины: • самая левая позиция; • самая правая позиция. Для очередного участника x возможны ровно три случая: • posx левее всех меньших — тогда пишем символ L; • posx правее всех меньших — тогда пишем символ R; • posx находится между ними — тогда пишем символ M. Глобальный минимум не кодируется, так как у него нет меньших элементов. Таким образом, любой текущий набор участников кодируется строкой s ∈ {L, R, M }∗ , записанной в порядке возрастания номеров. После этого задача уже формулируется не про самих школьников, а про то, как по этой строке быстро считать ответ.
Страница 6
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года
Как построить строку L/R/M с нуля Это нужно и для маленьких подзадач, и для инициализации полного решения. Пусть текущие участники имеют номера x1 < x2 < · · · < xk в порядке возрастания, а их позиции в ряду равны p1 , p2 , . . . , pk . Тогда: • x1 — текущий глобальный минимум, его пропускаем; • дальше поддерживаем mn = p1 ,
mx = p1 ;
• для каждого i ⩾ 2: – если pi < mn, пишем L и обновляем mn = pi ; – если pi > mx, пишем R и обновляем mx = pi ; – иначе пишем M. Это обычный линейный проход после того, как известны позиции текущих участников.
Подзадачи Подзадачи 1 и 10: n + q ⩽ 16 Здесь можно вообще не использовать специальную структуру. После каждого изменения: 1. строим текущий граф допустимых бросков напрямую по определению; 2. ищем в нём максимальный простой путь битмасочным DP: dp[mask][v] = существует ли путь, использующий mask и заканчивающийся в v. Сложность одного пересчёта равна
O(m2 2m ),
где m — текущее число участников. Для m ⩽ 16 этого более чем достаточно. Подзадачи 2, 4, 11, 13: n, q ⩽ 1000 Здесь уже можно использовать кодирование строкой L/R/M , но пока без сложных структур. После каждого запроса делаем всё заново: 1. восстанавливаем текущий порядок участников; 2. строим строку s за O(m); 3. считаем ответ по этой строке: • для t = 1 — линейным DP; • для t = 2 — прогоном по маленькому автомату. Страница 7
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года Итого получается O(m) на один запрос и
O((n + q)2 )
суммарно. Этого достаточно для ограничений порядка n, q ⩽ 1000. Подзадачи 3, 5, 12, 14: q = 0 Здесь строку нужно построить только один раз и только один раз по ней посчитать ответ. Сложность: O(n). Подзадачи 6 и 15: n = 1, a1 = 1, добавления по возрастанию номеров В этом частном случае каждый новый участник является новым максимумом по номеру. Значит, относительно всех меньших он может оказаться только: • либо слева от всех — символ L; • либо справа от всех — символ R. Символов M не бывает, а старые символы не меняются. То есть строка просто растёт справа, и на каждом запросе к ней дописывается одна буква L или R. Дальше: • для t = 1 обновляем несколько чисел за O(1); • для t = 2 делаем один переход автомата за O(1). Подзадачи 7, 8, 9, 16, 17, 18 Здесь уже требуется полное решение.
Полное решение для t = 1 Что нужно хранить Пусть уже обработан некоторый префикс строки s. Для будущих добавлений важны только две крайние вершины среди уже меньших: • левая крайняя; • правая крайняя. Поэтому достаточно хранить три величины: • f (s) — длина максимального пути; • dpL (s) — длина максимального пути, у которого один конец — левая крайняя вершина; • dpR (s) — длина максимального пути, у которого один конец — правая крайняя вершина. Это и есть всё состояние.
Страница 8
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года Почему этого хватает При добавлении одной новой вершины происходит ровно одно из трёх: • L: новая вершина соединяется только с правой крайней; • R: новая вершина соединяется только с левой крайней; • M: новая вершина соединяется с обеими крайними. Значит, новый лучший путь можно получить только так: • оставить старый лучший путь; • продлить путь, который заканчивался в левой границе; • продлить путь, который заканчивался в правой границе. Никакая другая информация о старом графе для будущего не нужна. Переходы по одной букве Символ L. Новая вершина становится новой левой границей и соединяется с прежней правой: ′ f = max(f, dpR + 1), L : dp′L = dpR + 1, ′ dpR = dpR . Символ R. Симметрично: ′ f = max(f, dpL + 1), R : dp′L = dpL , ′ dpR = dpL + 1. Символ M. Новая вершина цепляется к обеим границам, но сами границы не меняются: ′ f = max(f, dpL + 1, dpR + 1), M : dp′L = dpL , ′ dpR = dpR . Для пустой строки: f = 0,
dpL = 0,
dpR = 0.
Если строку нужно посчитать только один раз, то этого уже достаточно для линейного решения. Как пересчитывать это в дереве отрезков Каждый символ действует на тройку (f, dpL , dpR ) как некоторое преобразование. Поэтому любой отрезок строки можно понимать как преобразование, которое переводит состояние перед этим отрезком в состояние после него. Композиция двух соседних отрезков — это просто композиция соответствующих преобразований. Именно поэтому в вершине дерева отрезков удобно хранить не сам ответ на отрезке, а преобразование для этого отрезка. Аналогично случаю с одной буквой, удобно записать состояние в виде столбца f v = dpL . dpR Тогда каждую букву можно записать как max-plus матрицу размера 3 × 3. Страница 9
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года Max-plus матрицы Для символов L, R, M получаем:
0 −∞ 1 0 1 −∞ AL = −∞ −∞ 1 , AR = −∞ 0 −∞ , −∞ −∞ 0 −∞ 1 −∞ 0 1 1 0 −∞ . AM = −∞ −∞ −∞ 0
Пустая позиция даёт тождественное преобразование 0 −∞ −∞ 0 −∞ . I = −∞ −∞ −∞ 0 Если для двух соседних отрезков хранятся матрицы A и B, то для их объединения в дереве отрезков хранится max-plus произведение B ⊗ A, то есть сначала применяется левый отрезок, потом правый. В корне дерева лежит преобразование для всей строки, а ответ получается применением этого преобразования к начальному вектору 0 0 . 0
Как поддерживать строку L/R/M онлайн Это вторая часть полного решения. Дерево отрезков строится по порядку номеров, а не по текущему порядку в ряду. В листе с номером x хранится одна из следующих сущностей: • I, если участник ещё не добавлен; • I, если это текущий глобальный минимум; • матрица L; • матрица R; • матрица M. Иными словами, глобальный минимум просто не кодируется. Какие символы могут измениться после вставки Если новый участник добавляется слева, то измениться могут только текущие префиксные минимумы: • часть символов L перестаёт быть L и становится M; • если новый участник стал новым глобальным минимумом, старый глобальный минимум превращается из пустой позиции в R. Если новый участник добавляется справа, всё симметрично: • часть символов R превращается в M; • если появился новый глобальный минимум, старый глобальный минимум становится L. Именно это позволяет обновлять строку быстро. Страница 10
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года Что хранить дополнительно Храним две монотонные деки по номерам: • pref — все текущие префиксные минимумы в порядке возрастания номера; • suff — все текущие суффиксные минимумы в порядке возрастания номера. Первый элемент в обеих деках — текущий глобальный минимум. Вставка слева Пусть добавляется участник x. 1. Пока в конце pref стоит номер больше x, он перестаёт быть префиксным минимумом: • если это не старый глобальный минимум, его тип меняется L → M; • если это старый глобальный минимум, его тип меняется I → R. 2. После этого возможны два случая: • если x — новый глобальный минимум, его лист остаётся равным I, а сам x добавляется в начало обеих дек; • иначе x получает тип L и добавляется в конец pref. Вставка справа Полностью симметрично: • работаем с деком suff; • обычные элементы меняются R → M; • старый минимум при необходимости становится L. Почему это амортизированно быстро Каждый участник: • не более одного раза становится префиксным минимумом и не более одного раза перестаёт им быть; • не более одного раза становится суффиксным минимумом и не более одного раза перестаёт им быть. Значит, суммарно по всем запросам будет только O(n + q) удалений из дек. Каждое изменение типа — это одна точечная модификация листа в дереве отрезков, то есть O(log(n + q)). Итого суммарная сложность: O((n + q) log(n + q)).
Что меняется при t = 2 Идея остаётся той же самой: 1. текущий набор по-прежнему кодируется строкой над {L, R, M }; 2. эта строка по-прежнему поддерживается двумя монотонными деками; 3. дерево отрезков по-прежнему строится по порядку номеров. Меняется только то, какую информацию нужно хранить в вершине дерева. Страница 11
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года Почему трёх чисел уже недостаточно Для t = 1 хватало знать: • лучший уже готовый путь; • лучший путь, который можно продолжить через левую границу; • лучший путь, который можно продолжить через правую границу. Для t = 2 этого уже мало. Теперь будущее зависит ещё и от того, как текущая частичная конфигурация взаимодействует с двумя граничными вершинами. Интуитивно нужно различать такие вещи: • могут ли левая и правая границы быть концами будущего оптимального пути; • находятся ли они сейчас в одной компоненте или в разных; • если в одной, соединены ли они уже частью допустимого пути; • какую конфигурацию ещё можно корректно продолжить в один простой путь при добавлении новых вершин. То есть состояние по-прежнему определяется только поведением относительно двух границ, но теперь вариантов этого поведения уже не три, а конечное, но более заметное число. Автомат Удобно смотреть на эту ситуацию как на конечный автомат. Назовём две строки s и t эквивалентными, если для любого продолжения p выполнено f (s + p) − f (s) = f (t + p) − f (t). Иначе говоря, с точки зрения всех будущих продолжений строки s и t ведут себя одинаково, если после них всегда происходят одинаковые переходы и одинаково меняется ответ. Каждый класс такой эквивалентности можно считать состоянием автомата. При чтении очередного символа из {L, R, M } автомат: • переходит в новое состояние; • увеличивает текущий ответ на некоторое число. Для t = 1 после минимизации получается 6 состояний. Для t = 2 получается 20 достижимых состояний. Ниже мы будем пользоваться уже готовым автоматом для t = 2. Как получить эти 20 состояний Выписывать их вручную долго и не нужно. Гораздо удобнее сгенерировать автомат отдельной программой. Один из стандартных способов такой: 1. перебрать короткие строки над {L, R, M }; 2. для каждой строки точно посчитать значение f (s) маленьким brute force; 3. считать две строки эквивалентными, если они неразличимы по всем коротким продолжениям; 4. после стабилизации этого разбиения получить конечный набор достижимых состояний и таблицу переходов. В этой задаче стабилизация происходит быстро, и для случая t = 2 получается 20 состояний. После этого таблицу переходов можно просто захардкодить в решение. Страница 12
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года Что хранить в вершине дерева отрезков Для каждого состояния q храним результат применения всего отрезка: go[q] = (newState, ∆), где • newState — состояние, в которое попадём после чтения всех символов этого отрезка; • ∆ — насколько увеличится ответ. Для листа с символом L, R или M это просто фиксированная таблица переходов. Для пустой позиции или текущего глобального минимума хранится тождественное преобразование: go[q] = (q, 0). Как объединять две вершины Пусть для левого сына известно goL [q] = (mid[q], addL [q]), а для правого сына известно goR [q] = (toR [q], addR [q]). Тогда для родителя: mid = goL [q].state, go[q].state = goR [mid].state, go[q].add = goL [q].add + goR [mid].add. То есть это просто композиция преобразований: сначала читаем левый отрезок, потом правый. Если q0 — стартовое состояние автомата, то ответ в корне равен goroot [q0 ].add.
Инициализация полного решения Если начальный ряд уже задан, то перед обработкой запросов делаем следующее: 1. строим для него строку L/R/M с нуля; 2. выставляем тип каждой уже присутствующей вершины: • минимум → I; • остальные → L/R/M ; 3. одновременно собираем деки pref и suff: • все L и текущий минимум попадают в pref; • все R и текущий минимум попадают в suff. После этого все запросы уже обрабатываются онлайн.
Страница 13
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года
Сложность Пусть N = n + q. Тогда: • каждая вершина меняет тип лишь константное число раз; • суммарно происходит O(N ) изменений символов; • каждое изменение — это точечное обновление дерева отрезков. Следовательно: • для t = 1 время работы равно O(N log N ), память — O(N ); • для t = 2 асимптотика та же самая, потому что число состояний автомата постоянно: O(N log N ) по времени и O(N ) по памяти.
Итог Вся задача распадается на две почти независимые части: 1. перевести текущий набор участников в строку над {L, R, M }; 2. быстро посчитать ответ по этой строке. Для маленьких подзадач строку можно пересчитывать с нуля. Для полного решения: • строка поддерживается двумя монотонными деками; • значение по строке поддерживается деревом отрезков: – из max-plus матриц размера 3 × 3 для t = 1; – из преобразований автомата из 20 состояний для t = 2. Это и даёт итоговую сложность O((n + q) log(n + q)).
Решение 2 Скажем, что элемент массива имеет тип L, если нет элемента левее него с меньшим значением. Аналогично определим элементы типа R. Заметим, что глобальный минимум удовлетворяет обоим типам, поэтому его в решении будем рассматривать отдельно. Все остальные элементы, которые не удовлетворяют данным типам, будут иметь тип M. Рассмотрим, как устроены рёбра, исходящие из каждого из элементов в этом графе:
Страница 14
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года • Если элемент имеет тип L, то из него ведёт ровно одно ребро, ведущее в максимальный по значению элемент типа R, не превосходящий данный. • Если элемент имеет тип R, то из него ведёт ровно одно ребро, ведущее в максимальный по значению элемент типа L, не превосходящий данный. • Если элемент имеет тип M, то из него ведёт два ребра в максимальные по значению элементы типов L и R. Решим сначала версию с ориентированным графом. Будем рассматривать элементы в порядке возрастания значений. Элементы, имеющие тип M, проигнорируем, а другие элементы равных типов объединим в блоки подряд идущих. Минимальный элемент для удобства можно добавить в отдельный блок. Нетрудно видеть, что самый длинный путь из элементов типов L и R определяется однозначно, и равен количеству блоков, идущих раньше (по значениям) чем блок, в который попал соответствующий элемент. Таким образом, длина самого длинного пути, начинающегося в элементах типа L или R имеет длину, равную количеству блоков −1. Пути, начинающиеся из элементов типа M, сразу же попадают в один из блоков, поэтому чтобы учесть самый длинный такой путь, достаточно рассмотреть элемент типа M с максимальным значением. Чтобы эффективно поддерживать блоки, можно поддерживать элементы типов L и R в двух стеках рекордов и, при добавлении элемента с одной из сторон, надо удалить суффикс элементов соответствующего стека и добавить в него новый элемент. Таким образом, для решения задачи достаточно уметь обрабатывать следующее: • Изменить тип элемента с L или R на M. • Добавить элемент с типом L или R. • Найти количество блоков, описанных выше. • Найти количество блоков, идущий до максимального элемента типа M. Блоки можно поддерживать с помощью std::set. Чтобы избежать других структур данных для последнего запроса достаточно не явно находить количество блоков, а проверять, правда ли, что максимальный элемент типа M (если такой элемент существует) по значению больше минимального элемента в последнем блоке. Данное решение можно реализовать за O((n + q) log(n + q)). Данное решение обобщается до случая с неориентированным графом. Будем так же поддерживать блоки, но теперь понадобится дополнительная информация. Назовём стоимостью элемента типа L или R количество элементов типа M больших по значению, чем данный, но меньших, чем ближайший больший элемент типа L или R. Для каждого элемента будем поддерживать его стоимость. Это можно сделать с помощью дерева фенвика или с помощью std::set, если заметить, что все стоимости ⩾ 3 в данной задаче эквивалентны, поэтому достаточно рассматривать не более 3х ближайших больших элементов типа M для каждого. Далее будем относить элементы типа M к блоку, в который попадает элемент типа L или R, в стоимости которого он учитывается. Можно показать, что самый длинный путь начинается в одном из двух последних блоков и заканчивается в одном из двух первых блоков, не считая минимума, или в самом минимальном элементе. Чтобы учесть все случаи, достаточно для каждого блока хранить стоимость первого/последнего и дополнительно двух максимальных по стоимости элементов в нём. Далее есть два пути: • Рассмотреть много случаев и обновить через них ответ. Описание всех случаев заняло бы очень много места, поэтому они в разборе опущены. • Заметить, что мы можем оставить O(1) элементов из первых и последних двух блоков, а так же минимальный элемент. От всех остальных блоков важна только суммарная стоимость максимальных элементов в них. Таким образом, задачу можно свести к троичной строке не очень Страница 15
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года большой длины. Для всех таких строк можно заранее посчитать ответ перебором или динамикой. Такой способ позволяет избежать ручной обработки всех случаев, что сильно упрощает реализацию. Такое решение можно реализовать за O((n + q) log(n + q)) с большой константой.
Страница 16
Решения — 2 день
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года
Задача 5. Обобщённые шахматы
Краткое условие задачи Дана доска n × n (1 ⩽ n ⩽ 400), клетка (i, j) покрашена в цвет aij . Для каждой пары r, c (1 ⩽ r, c ⩽ n) нужно найти минимальное количество клеток для перекраски brc , необходимое, чтобы прямоугольник из первых r строк и первых c столбцов стал правильно раскрашенным: • используется не более двух разных цветов; • соседние по стороне клетки имеют разные цвета.
Краткая идея решения Для фиксированного прямоугольника (r, c) нужно выбрать два цвета c0 , c1 (для клеток с чётной и нечётной суммой координат). Для каждой чётности нам нужны два самых частых цвета. В полном решении используется сжатие цветов и поддержка двух максимумов за O(1), что даёт O(n3 ) времени на полное решение. Подробный разбор: Подзадача 1. (n ⩽ 50) Вместо того, чтобы считать количество клеток, которые нужно перекрасить — будем наоборот считать количество клеток, которые не поменяют цвет. Количество таких клеток мы хотим максимизировать. У нас есть два типа клеток (i, j) — у которых (i + j) mod 2 = 0 и (i + j) mod 2 = 1, и они должны быть разных цветов. Зафиксируем подпрямоугольник (r, c), для которого мы решаем задачу. Нам нужно зафиксировать два цвета col1 и col2 , чтобы максимизировать количество клеток с (i + j) mod 2 = 0 цвета col1 + количество клеток с (i + j) mod 2 = 1 цвета col2 . Сделаем структуру данных, в которую мы будем уметь добавлять пару (col, cnt) и поддерживать два максимальных cnt у разных цветов col. Переберем все клетки подпрямоугольника (r, c) и посчитаем для каждого цвета и типа клетки (остатка по модулю два) количество вхождений. После этого посчитаем два максимума для клеток типа 1 и типа 2 (с помощью структуры, которую мы определили выше). Теперь, если самый частый цвет среди клеток типа 1 и клеток типа 2 различаются, то нам выгодно оставить их. Иначе нам нужно рассмотреть два варианта: второй по частоте цвет среди клеток типа 1 + самый частый цвет среди клеток типа 2, и самый частый цвет среди клеток типа 1 + второй по частоте цвет клеток типа 2. Возьмем максимум среди этих возможных вариантов, и ответом для подпрямоугольника (r, c) будет rc − количество клеток, которые сохранили цвет. Асимптотика O(n4 log n), где log для того, чтобы считать для каждого цвета количество его вхождений. Подзадача 2. (n ⩽ 200) Эта подзадача близка к полному решению, но в ней можно реализовать структуру, которая поддерживает два максимума за log, либо реализовать структуры данных не самым оптимальным образом. Зафиксируем r и найдем ответ для всех подпрямоугольников (r, c). Будем перебирать c по возрастанию и поддерживать для каждого цвета и типа клетки, количество вхождений этого цвета в текущий подпрямоугольник (r, c). Также, будем для обоих типов поддерживать два самых частых цвета, как в подзадаче 1. При переходе от c к c + 1 честно добавим r клеток, которые добавляются при расширении прямоугольника. Таким образом, получаем решение за O(n3 log n), где log от допустимой неэффективной реализации структуры с двумя максимума на базе map или set. Подзадача 3. (Только два различных цвета)
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года В этой подзадаче всего два цвета, поэтому для каждого подпрямоугольника у нас всего две возможные цветовые конфигурации и мы можем явно посчитать ответ для каждой из них за O(n2 ). Подзадача 4 (не более 10 разных цветов) В этой подзадаче мы можем перебрать пару цветов, в которые будет раскрашена доска и для каждого подпрямоугольника проверить конфигурацию за O(n2 ). Таким образом, время работы O(102 × n2 ). Подзадача 5 (не более 100 разных цветов) Эту группу тестов могли проходить решения с недостаточно эффективной реализацией следующих подгрупп. Подзадача 6 (не более 10000 разных цветов) В этой подзадаче ожидается полное решение, за исключение того, что чтобы поддерживать количество вхождений какого-то цвета, достаточно создать массив на 10000 элементов, вместо поддержки счетчиков за логарифм. Полное решение Сначала сожмем координаты, то есть сделаем так, чтобы все числа оказались меньше, чем n2 . Сжатие координат можно реализовать с помощью хеш-таблицы или с помощью сортироваки и бинарного поиска. Этой займет время O(n2 ) или O(n2 log n). После этого реализуем решение из подзадачи 2, в котором мы за O(1) поддерживаем количество вхождений какого-то цвета и за O(1) поддерживаем два максимума. Получаем решение за O(n3 ), которое без проблем сдается.
Задача 6. Ночь, улица, фонарь, аптека Подгруппа 1: t = 1, n ⩽ 10 Переберём все подмножества фонарей. Осталось проверить, что подмножество фонарей является экономным. Для этого можно перебрать для каждого фонаря, смотрит он вправо или влево, и явно проверить, выполняется ли условие их экономности. Данный перебор работает за O(3n ), так как каждому перебранному варианту может соответствовать троичная маска: 0 - мы не взяли фонарь в экономное множество, 1 — мы взяли фонарь, и он направлен влево, 2 - мы взяли фонарь, и он направлен вправо.
Подгруппа 2: t = 1, xi − si ̸= xj и xi + si ̸= xj − sj Описанное условие означает, что все фонари на отрезке нужно направить вправо. Будем считать dpi,x — количеством подмножеств фонарей, если мы рассматриваем фонари с номерами ⩾ i, и подмножество можно направить вправо так, чтобы самый левый освещенный отрезок начинался в позиции x. При пересчёте dpi,x = dpi+1,x , кроме ситуации, когда мы используем i-й фонарь. В таком случае получается обновление dpi,xi = 1 + dpi+1,xi +si . Получаем решение за O(n + X), где X — максимальное ограничение на координаты.
Подгруппа 3: t = 1, si ̸= sj Рассмотрим, как устроен произвольный ответ. Сначала сколько-то первых фонарей у нас направлены вправо. Далее, если дальше фонарь был направлен влево, то теперь следующие фонари должны освещать его правый конец, тогда все оставшиеся фонари светят влево. Таким образом, у нас сначала сколько-то фонарей направлены вправо, а потом сколько-то влево. Заметим, что в этой подгруппе каждое подмножество можно определить единственным способом (кроме случая, если оно состоит ровно из одного фонаря). Если у нас было направление и вправо, и влево, то ориентация однозначна, а иначе у нас все фонари направлены в одну сторону, и, чтобы можно было развернуть, надо, чтобы все si были одинаковыми. Тогда посчитаем ответ следующим образом: посчитаем dp аналогично второй подгруппе, это найдёт количество способов начать с левой границей в x. Посчитаем аналогичное dp в обратном порядке по правым границам, тогда мы найдём количество способов закончить в x.
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года Теперь переберём точку, где соприкасаются префикс и суффикс, и перемножим значения dp. Не забудем прибавить все отдельные значения dp, чтобы учесть направления только в одну сторону. Осталось вычесть из ответа n, так как мы два раза учли подмножество из одного фонаря. Получаем решение за O(n + X), где X — максимальное ограничение на координаты.
Подгруппа 4: t = 1, si = sj Аналогично предыдущей подгруппе посчитаем две dp. Теперь поймём, как устроен ответ: это либо все направлены в одну сторону, тогда надо просуммировать значения любой из dp, либо у нас есть фонари направленные и вправо, и влево, тогда надо перебрать точку соприкосновения и перемножить. Получаем решение за такую же асимптотику.
Подгруппа 5: t = 1, n ⩽ 1000 Напишем dpi,x — количество способов выбрать подмножество экономных фонарей вместе с их ориентацией, если мы рассмотрели только первые i фонарей, а последняя освещённая координата x. Тогда переходы в этой динамике следующие: • dpi+1,xi = dpi,xi −si + 1. Мы направли фонарь i влево. • dpi+1,xi +si = dpi,xi + 1. Мы направли фонарь i вправо. Осталось понять, какие состояния мы учли несколько раз. Экономное множество фонарей может учитываться несколько раз, если каждый из фонарей можно ориентировать в другую сторону, и подмножество останется экономным. Очевидно, что в таком множестве все фонари будут направлены в одну сторону, поскольку иначе будет разрыв. Тогда i1 , i2 , . . . , ik можно ориентировать как влево, так и вправо, если выполняется xi1 + si1 = xi2 , xi2 + si2 = xi3 , . . . , xik−1 + sik−1 = xik и si1 = si2 = . . . = sik . Тогда ответ на задачу будет суммой всех значений dp минус количество таких подмножеств. Динамика считается за O(n2 ) или за O(n2 ·log(n)), если динамику хранить в std::map. А количество таких множеств тоже считается за O(n2 ), так как максимальная такая «цепочка» имеет длину n, и мы можем её явно перебрать.
Подгруппа 6: t = 1 Осталось научиться считать за линейное время dp, а также количество «цепочек». Для пересчёта динамики можно заметить, что для очередного i меняются только 2 состояния по x. Поэтому можно хранить dpx — количество экономных подмножеств, оканчивающихся в точке x. И для очередного i пересчитать следующим образом все состояния: • dpxi +si := dpxi +si + dpxi + 1. • dpxi := dpxi + dpxi −si + 1. Для подсчёта цепочек можно написать dp2i — количество «цепочек», которые кончаются на i-м фонаре. Тогда для того, чтобы пересчитать количество «цепочек», оканчивающихся на j-м фонаре, достаточно проверить, есть ли фонарь в координате xj − sj , и, если он есть (пусть его номер i), тогда, если si = sj , то dp2j = dp2i + 1, иначе dp2j = 1.
Подгруппа 7: t = 2, если xi = xi+1 , то si ̸= si+1 Также посчитаем динамику из подгруппы 6. Тогда если у нас в очередной координате ровно один фонарь, то переходы остаются такими же, иначе они следующие. Пусть номер фонаря, для которого мы пересчитываем состояния, равен i, первый из его прожекторов имеет силу освещения s1 , а второй s2 . Тогда:
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года • dpxi +s1 := dpxi +s1 + dpxi + dpxi −s2 + 2. Первый прожектор ориентировали вправо. • dpxi +s2 := dpxi +s2 + dpxi + dpxi −s1 + 2. Второй прожектор ориентировали вправо. • dpxi := dpxi + dpxi −s1 + dpxi −s2 + 2. Ровно один из прожекторов ориентировали влево. Осталось также посчитать, сколько есть подмножеств, у которых можно поменять ориентацию, чтобы подмножество осталось экономным. Но при двух прожекторах на одном фонаре у нас может быть более сложная конструкция: мы можем поменять между собой направления двух прожекторов местами. Поэтому для учёта «цепочек» мы можем написать dpchainx,y — количество «цепочек», которые заканчиваются в координате x, и, если мы поменяем ориентацию прожекторов (если один прожектор светил влево, другой вправо, то после смены ориентации будет наоборот) у последнего фонаря, то последняя освещённая координата увеличится на y. Тогда в ней переходы следующие в случае (мы говорим, что s1 > s2 ): • dpchainxi ,s1 := dpchainxi ,s1 +1+dpchainxi −s1 ,s1 . Мы в фонаре поставили прожектор s1 , который светит влево. • dpchainxi ,s2 := dpchainxi ,s2 +1+dpchainxi −s2 ,s2 . Мы в фонаре поставили прожектор s1 , который светит вправо. • dpchainxi +s2 ,s1 −s2 := dpchainxi +s2 ,s1 −s2 + 1 + dpchainxi −s1 ,s1 −s2 . Мы в фонаре поставили прожектор s2 , который светит вправо, и прожектор s1 , который светит влево. Тогда, если мы поменяем ориентацию двух фонарей, то станет покрыта координата xi + s1 . В случае, если у фонаря ровно один прожектор, то переходы будут следующие: • dpchainxi ,si := dpchainxi ,si + 1 + dpchainxi −si ,si . Эту динамику можно хранить в std::map<int, map<int, int». Тогда заметим, что все «цепочки» были посчитаны в этой динамике, так как, если мы меняем местами прожекторы (для лучшего понимания можно считать, что, если был поставлен один прожектор, то было поставлено два прожектора, один из которых освещает отрезок длины 0), то каждый отрезок, освещённый одним фонарём, сдвигается на дельту сил прожекторов. А значит, ответ — сумма всех состояний dp минус сумма всех состояний dpchain.
Полное решение: В последней подгруппе требуется понять, что нужно немного поменять переходы: • dpxi +si := dpxi +si + 2 · dpxi + dpxi + 3. • dpxi := dpxi −si + 2 · dpxi + dpxi + 2. А dpchain пересчитывается следующим образом: dpchainxi ,si := dpchainxi ,si + 2 + 2 · dpchainxi −si ,si .
Задача 7. Марсианский рюкзак Переформулировка задачи Для каждого префикса из первых i предметов нужно найти минимально возможное значение побитового OR выбранного подмножества, у которого суммарная стоимость не меньше C. Если такого подмножества нет, ответ равен −1. Подзадача 1: n ⩽ 20, k ⩽ 10 Можно просто перебрать все подмножества первых i предметов для каждого i. Для каждого подмножества считаем сумму стоимостей и побитовое OR странностей. Среди подмножеств с суммой не меньше C берём минимальный OR. Асимптотика O(20 + 21 + . . . + 2n ) = O(2n ).
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года Подзадачи 2 – 3: n ⩽ 50 000, k ⩽ 10 Для фиксированной маски P x максимальная суммарная стоимость подмножества с общей странностью y ⊆ x равна Fi (x) = j⩽i, wj ⊆x cj , где запись wj ⊆ x означает, что wj является подмаской x, то есть (wj & ∼ x) = 0. Значит, ответ для префикса i — это минимальная маска x, для которой Fi (x) ⩾ C. Будем поддерживать значения Fi (x) напрямую: когда приходит предмет с маской wi и стоимостью ci , нужно прибавить ci ко всем маскам x, для которых wi ⊆ x. После этого достаточно найти минимальную маску x с Fi (x) ⩾ C. Асимптотика O n · 2k . Подзадачи 4 – 5: n ⩽ 1 000 000, k ⩽ 19, wi — степени двойки или n ⩽ 2000 В данных подзадачах, чтобы найти нужный ответ для префикса p, можно идти жадно по битам сверху вниз. вначале в маске разрешены все биты, а текущая доступная суммарная стоимость PПусть p равна T = i=1 ci . Далее идём по битам от старших к младшим и пытаемся удалить текущий бит, за O(p) находим T ′ – новую сумму ci по подходящим предметам. Если T ′ < C, то возвращаем бит, иначе оставляем его нулем. Далее переходим к меньшему биту. Асимптотика O(n2 k), что достаточно для решения подзадачи 4. Для решения подзадачи 5 можно просимулировать алгоритм выше, заметив, что T ′ можно вычислить как вычитание из T суммы ci с wi , равными нужной степени двойки. Подзадача 6: n ⩽ 500 000, k ⩽ 16 Для данной подзадачи нужно применить технику «Meet In The Middle». Каждую маску wi представим в виде wi = (hi , ℓi ), где: • hi — старшие p бит, • ℓi — младшие q бит. Аналогично ответ будем искать в виде ansi = (Hi , Li ), где сначала минимизируем старшую часть Hi , а затем при фиксированной Hi минимизируем младшую часть Li . Для нахождения старшей части применяем решение из подзадачи 3 за O(n · 2p ). Тогда при добавлении нового предмета Hi либо не изменяется (остается равным Hi−1 ), либо уменьшается. Если Hi < Hi−1 , то пересчитаем значение функции Fi (x) для всех Hi · 2q ⩽ x < (Hi + 1) · 2q . Для этого по всем j, таким, что 1 ⩽ j ⩽ i, и если hj ⊆ Hi , то в Fi (Hi · 2q + lj ) добавим cj , а далее сделаем SOS-DP для F в промежутке [Hi · 2q , (Hi + 1) · 2q ). Иначе, если Hi = Hi−1 и hi ⊆ Hi , то обновим нужные значения F за O(2q ). Итого, так как уменьшений H не более O(2p ), то решение суммарно работает за k k O(2k · q + n · (2p + 2q )). При p = q = 2 2 решение работает за O(2k · k + n · 2 2 ). Полное решение Будем строить ответы сразу для целого отрезка префиксов и сразу по всем битам. Пусть старшие биты ответа уже зафиксированы, а осталось определить ещё t младших бит. Для текущего рекурсивного вызова будем хранить: • число pref — уже зафиксированная часть ответа в старших битах; • отрезок префиксов [L, R], для которых все ответы имеют один и тот же уже построенный старший префикс; • массив cnt длины 2t . Массив cnt построен по первым L − 1 предметам. Для каждой маски s длины t значение cnt[s] равно суммарной стоимости тех предметов, которые: • среди уже обработанных старших битов не противоречат маске pref, то есть их старшие биты являются подмаской соответствующих битов ответа; • на оставшихся t младших битах точно равны s.
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года Иначе говоря, мы сгруппировали все предметы, которые ещё могут входить в ответ, по их оставшейся младшей части. Как определить очередной бит? Пусть сейчас мы определяем старший из оставшихся t бит, то есть бит с номером t − 1 внутри текущего массива cnt. Разобьём все маски на две половины: • нижняя половина — маски, у которых этот бит равен 0; • верхняя половина — маски, у которых этот бит равен 1. Если мы хотим поставить текущий бит ответа в 0, то брать можно толькоP предметы из нижней половины. Максимальная суммарная стоимость таких предметов равна S0 = s<2t−1 cnt[s]. Отсюда сразу следует критерий: • если S0 ⩾ C, то существует допустимое решение с текущим битом 0; • если S0 < C, то никакое решение с текущим битом 0 невозможно, значит, этот бит обязан быть равен 1. Этого достаточно, так как, если текущий бит ответа равен 0, то остальные более младшие биты мы в лучшем случае можем поставить в 1. Значит, мы действительно учитываем все предметы, которые можно взять при текущем бите 0. Где разбивается отрезок префиксов? Из-за монотонности ответов существует такая граница M , что • для префиксов L, L + 1, . . . , M − 1 текущий бит ответа равен 1; • для префиксов M, M + 1, . . . , R текущий бит ответа равен 0. Найдём её одним проходом. P Изначально массив cnt уже соответствует первым L−1 предметам, а значение S0 = s<2t−1 cnt[s] соответствует тем из них, которые можно брать при текущем бите 0. Теперь будем последовательно рассматривать предметы с номерами L, L + 1, . . . , R. Для очередного предмета i проверим, может ли он участвовать в решении текущего узла: • на уже зафиксированных старших битах его маска не должна содержать единиц там, где в pref стоит ноль; • текущий рассматриваемый бит у него должен быть равен нулю, если мы хотим считать сумму S0 . Как только после добавления очередного предмета можно впервые получить S0 ⩾ C, мы нашли позицию M . Время поиска границы на одном узле равно O(R − L + 1). После того как граница M найдена, остаются две рекурсии. Левая часть рекурсии отвечает за префиксы [L, M − 1]. Теперь текущий бит уже зафиксирован как единица, значит, на этом бите предмет может иметь и 0, и 1. Следовательно, для каждой маски младших t − 1 бит нужно просто сложить две половины: next1 [s] = cnt[s] + cnt[s + 2t−1 ] для 0 ⩽ s < 2t−1 . Стоимость построения массива для левой части: O(2t ). Правая часть рекурсии отвечает за префиксы [M, R]. В этом случае брать можно только нижнюю половину: next0 [s] = cnt[s] для 0 ⩽ s < 2t−1 . Но есть важный нюанс: массив для правого сына должен соответствовать уже первым M − 1 предметам, а массив cnt был построен только для первых L − 1. Поэтому во время поиска границы M мы одновременно поддерживаем и массив next0 : все подходящие предметы с текущим битом 0, встретившиеся на позициях от L до M − 1, добавляются в нужную ячейку по своим младшим t − 1 битам. Тогда к моменту запуска правой рекурсии массив уже готов.
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года Остаётся отдельно обработать префиксы, для которых ответа вообще не существует. Это делается заранее: найдём первый префикс, у которого суммарная стоимость всех предметов стала хотя бы C. Для всех предыдущих префиксов выводим −1, а рекурсию запускаем только с этого места. Итого, решение за O(nk + 2k k).
Задача 8. Хорошие раскраски — 8 Подзадача 1. В случае n = 3 ответ равен k(k − 1), если все рёбра активны и k в ином случае.
Подзадача 2. Пусть Γi (1 ⩽ i < m) — это грань, содержащая на своей границе ребро li → li+1 , а Γ0 — это грань, содержащая на своей границе ребро lm → l1 . Тогда можно сначала раскрасить грань Γ0 , на это есть k способов, затем останется (k −1) свободных цветов для грани Γ1 , а если продолжить процесс раскраски граней в порядке Γ2 , . . . , Γm далее, то для каждой очередной грани будет доступно (k − 2) цветов. Таким образом, в зависимости от n ответ на задачу будет равен: answer = k, answer = k(k − 1)(k − 2)
n=3 n−5 2
n⩾5
Подзадача 3. В этом случае, если все рёбра не активны, то ответ равен k, а в ином случае, если будет активно ровно x рёбер, то грани объединятся в x граней, которые соединены по циклу друг с другом. Количество способов раскрасить x таких граней в k цветов можно вычислить с помощью метода динамического программирования: • dp1 [i] — количество способов раскрасить i граней в k цветов так, чтобы любые две грани i и i + 1 имели различные цвета, а также чтобы первая и последняя грань имели различные цвета. • dp2 [i] — количество способов раскрасить i граней в k цветов так, чтобы любые две грани i и i + 1 имели различные цвета, но при этом первая и последняя грани должны иметь один и тот же цвет. Очевиден базовый случай dp1 [1] = 0, dp2 [2] = k. А переходы расписываются так: dp1 [i] = dp1 [i − 1] · (k − 2) + dp2 [i − 1] · (k − 1) dp2 [i] = dp1 [i − 1]
Подзадачи 4–5. В эти подзадачи заходили переборные решения. Например, авторское решение имеет время работы O((q + 1) · (n3 + k n · n)) и устроено следующим образом: • Явно строится граф соседних граней в исходном графе. • С помощью алгоритма Флойда-Уоршелла грани разбиваются на группы, которые должны объединиться в одну грань. • Перебираются всевозможные k n раскрасок исходных граней и явно проверяются на корректность.
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года
Подзадача 6. Для решения этой подзадачи достаточно было заметить, что ответ равен 0, если в дереве есть вершина нечётной степени, и равен 2 во всех остальных случаях.
Подзадача 7. Замечание. Здесь и далее мы будем обозначать χ(n) — как количество способов раскрасить n граней, соединённых по циклу, используя k цветов. Совместим идеи из 2-й и 3-й подзадач: сначала раскрасим грань Γ0 , которая накрывает дерево сверху, а затем будем раскрашивать грани в порядке их вложенности. Причём грани, ограниченные сверху одной и той же вершиной дерева, будем раскрашивать одновременно. Если вершина v является корнем дерева, то требуется раскрасить deg v − 1 граней, это можно v) сделать χ(deg способами. Если же v не является корнем, то под ней находится deg v − 2 граней, и k v) их можно раскрасить χ(deg k(k−1) способами. Таким образом, требуется перемножить эти величины по всем нелистовым вершинам v, полученное значение и будет ответом на задачу.
Подзадачи 8–10. Назовём вершину v висячей, если она не является листом и соединена не более чем одним активным ребром с другими вершинами. Заметим, что от удаления висячей вершины ответ не изменяется, поэтому идея решения этих подзадач заключается в том, чтобы отвечать на запросы независимо и наиболее эффективным образом уметь избавляться от таких вершин. Авторское решение предлагает воспользоваться тем, что в задаче явно задан массив предков pi < i, а поэтому избавиться от висячих вершин можно в два прохода: • Сначала перебираем вершины в порядке от n до 1, если вершина v является листом, то она не висячая и она не удаляется. В ином случае вершина удаляется только тогда, когда в неё не ведут активные рёбра из неудалённых вершин с большими номерами. • Во втором проходе будем рассматривать вершины v в порядке от 1 до n. Если вершина v является корнем своей компоненты (то есть из неё наверх не исходит активное ребро в неудалённую вершину) и при этом эта вершина имеет единственного сына, то такая вершина удаляется. После двух таких проходов в дереве не остаётся висячих вершин. Но, возможно, дерево распадается на компоненты связности. Заметим, что мы всё также можем раскрашивать грани в порядке ′ вложенности, и каждая вершина v, которая является корнем, будет давать множитель degk v к ответу, deg′ v а все остальные нелистовые вершины будут давать множитель k(k−1) . Представленное решение имеет асимптотику O(n · q), а также быстро работает, так как отсутствуют прыжки по памяти и вся работа, по сути, совершается в двух-трёх циклах for.
Подзадача 11. В этой подзадаче предлагается сжать исходное дерево до размера 4q так, чтобы ответ от этого не изменился с точностью до домножения на константный множитель M . Делать это достаточно сложно, так как требуется проверять достаточно много случаев, поэтому при самостоятельной реализации этой идеи могут потребоваться стресс-тесты. Общая идея заключается в том, чтобы разбить все рёбра на два класса: постоянные и нестабильные. Постоянными мы назовём рёбра, которые активны на протяжении всех запросов, нестабильными те рёбра, которые изменяют своё состояние в одном из запросов. Заведём массив e, где e(v) — количество вершин на внешнем цикле, которые соединены постоянными рёбрами с v. Для инициализации положим, что e(v) = 1 для листьев v и e(v) = 0 для всех остальных вершин. Соответственно, мы перестаём считать, что цикл проходит именно через листья дерева, а предполагаем, что он проходит через какие-то другие (назовём их виртуальными) вершины, которые учтены в значениях e(v). Ясно, что от этого ответ на задачу не изменится. Далее вычислим для каждой вершины v величину:
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года • min f (v) — максимальное количество непересекающихся путей, которые ведут вниз по дереву от вершины v в виртуальные вершины по постоянным рёбрам. Тогда можно сжать дерево, используя следующие манипуляции: • Выделить цепочки вершин вида v1 → v2 → . . . → vl , где каждая пара соседних вершин в цепочке соединена ребром и вершины v2 , . . . , vl−1 имеют ровно двух соседей. Тогда такие цепочки можно объединить в одно ребро, соответствующим образом модифицировав последовательность запросов — новое ребро будет активным тогда и только тогда, когда активны все рёбра из исходной цепочки. Затем следует выделить опорные вершины, то есть те вершины v, для которых выполнено min f (v) ⩾ 2. Все вершины v, из которых по рёбрам, ведущим наверх, достижима какая-то отличная от v опорная вершина и для которых выполнено min f (v) ⩾ 1, будем называть предсказуемыми. Такие вершины интересны тем, что они никогда не будут удалены в ходе последовательного удаления висячих вершин. Поэтому каждую предсказуемую вершину можно переподвесить к виртуальному корню −1, а в её бывшем предке p увеличить значение e(p) на единицу, это никак не изменит ответ на задачу. Вершину −1 для удобства мы будем считать опорной (но в ответе для неё множитель считать не будем, так как она не является реальной вершиной, а выступает удобной записью для факта, что нам не важно, куда именно подвешена вершина v). Если вершина v подвешена за вершину −1 и min f (v) совпадает с количеством её сыновей, то такая вершина будет давать постоянный вклад в ответ, который можно учесть в множителе M , после чего, удалив эту вершину из дерева, всех её сыновей переподвесить к вершине −1. Подробный анализ показывает, что после сжатия дерева таким образом останется не более 4q вершин. Таким образом, решить эту подзадачу можно за время O(n + q 2 ).
Подзадача 12. Попробуем оптимизировать решение за O(nq) другим способом, воспользовавшись тем, что высота дерева h не превосходит 20. Идея решения заключается в том, чтобы явно поддерживать дерево, которое остаётся после удаления висячих вершин (см. решение подзадач 8–10). Для этого достаточно разделить вершины на три типа: • N — вершины, удалённые после первого прохода; • S — вершины, удалённые после второго прохода; • P — вершины, которые не будут удалены в ходе алгоритма. Теперь рассмотрим процесс удаления ребра v → pv . Сначала следует пробежаться по активным рёбрам вверх по вершинам, начав с вершины pv , до того момента, пока в очередную вершину не будет входить ещё какое-то активное ребро снизу, соединяющее её с вершиной P -класса, либо пока мы не дойдём до корня дерева. Все посещённые вершины перейдут в класс N . Если мы остановились в вершине, в которую ведёт ещё одно ребро, то в случае, если это ребро единственное, следует дальше продолжать подниматься вверх по активным рёбрам. Если мы остановились из-за того, что из очередной вершины u не исходит активного ребра вверх, то требуется спуститься вниз от вершины u до первой вершины, которая будет листом или у которой будет два сына P , соединённых с ней активными рёбрами. Все посещённые вершины следует отметить классом S. Если же мы дошли до вершины, в которую ведёт ещё одно активное ребро из вершины типа P , то не требуется дополнительно изменять классы вершин. Так как мы изменяем классы у вершин по одной, то можно с лёгкостью пересчитывать ответ. Данный алгоритм работает за время O(n + q · h).
Тридцать восьмая всероссийская олимпиада по информатике, заключительный этап Профиль «программирование», Москва, 22-28 марта 2026 года
Подзадачи 13–15. Есть два подхода для решения задачи на полный балл, оба работают за время O(n + q log n), но основаны на разных принципах. Подход 1. (D&Q) Заметим, что можно слегка модифицировать решение подзадачи 11 (требуется дополнительно обрезать из каждой компоненты стабильное или нестабильное ребро, ведущее наверх, которое гарантированно состоит из висячих вершин) и применить его в методе разделяй и властвуй. Сперва сожмём дерево, а затем разделим запросы на две примерно равные половины и решим задачу для этих половинок запросов рекурсивно. То есть будем сжимать дерево под запросы и снова делить их на две равные группы. Так как дерево, соответствующее отрезку из q запросов, по размеру не превышает O(q), то такое решение будет работать за O(q log q). Подход 2. (Структуры данных): Основан на том, чтобы поддерживать сжатое дерево на вершинах, оставшихся в P