A. Двоичная строка
Для начала заметим, что задача не имеет решений тогда и только тогда, когда выполняется одно из двух условий:
- Либо |b - c| > 1
- Либо b = 0, c = 0, и при этом a ≠ 0 и d ≠ 0
Для остальных случаев будем решать в два этапа: Сначала соберем минимальную строку, которая будет удовлетворять условиям на строки 01 и 10, а затем допишем после первого встреченного нуля a - 1 ноль, а после первой встреченной единицы d - 1 единицу. Очевидно, что условия на 01 и 10 от таких действий не испортятся.
B. Поезд и туннель
Разобьем весь поезд на отрезки вагонов без света. Будем идти по каждой группе из таких вагонов, и в том вагоне, на котором суммарная длина вагонов становится не меньше h, будем включать свет. Очевидно, что данная стратегия дает наименьший результат. Также нужно не забыть включить свет в первом и последнем вагонах: при въезде в туннель и выезде из него, соответственно, эти вагоны образуют темный момент времени.
C. Красивое разбиение
Первый элемент массива входит либо в M1, либо в M2. Не умаляя общности, будем считать, что он входит в M1. Тогда a[1] делится на gcd(M1), то есть gcd(M1) — делитель a[1].
Переберем все делители a[1] (их не больше 1344 для чисел до 109). Рассматривая текущий делитель d, возьмем все элементы массива, делящиеся на d, в M1 (так как от этого gcd(M1) не станет меньше d, а чем меньше элементов в M2, тем gcd(M2) больше), а все остальные элементы в M2 и обновим ответ величиной min(gcd(M1), gcd(M2)). Заметим, что мы можем пренебречь тем, что M2 будет пустым, считая в этом случае gcd для него равным бесконечности, поскольку все элементы в таком случае делятся на d, то и gcd(M2) будет не меньше d.
Асимптотика решения — O(sqrt(a[1]) + d(a[1])·n), где d(a[1]) ≤ 1344.
D. Подготовка задач
Для начала решим задачу, если нет запросов на изменение времен. Из массива ti сгенерируем новый массив cntj, в котором будем хранить количество задач, на которые необходимо потратить j минут, а также предподсчитаем массив его префиксных сумм. Тогда количество времени, которое потратит каждый друг, если их всего k, можно посчитать за O(MAX / k), где MAX — максимальное необходимое на задачу время (просто перебрав, на какие задачи потребуется 1, 2, ... MAX / k минут). Как известно, суммарное время работы такого алгоритма для всех k от 1 до MAX равно O(MAXlog(MAX)).
Теперь посмотрим, что происходит, когда время, необходимое на задачу, изменяется с t на t + 1. Ответы поменяются только для k являющихся делителями t. Поскольку максимальное количество делителей у чисел до 5·105 равно 200, то можно просто их все перебрать за время пропорциональное их количеству и обновить ответ только для них.
Аналогично, если время изменяется с t на t - 1, то ответы меняются для чисел, которые являются делителями t - 1.
E. Похожее метро
В задаче требовалось найти наибольшую по размеру пару изоморфных друг другу связных поддеревьев данных деревьев. Будем решать эту задачу методом динамического программирования.
Посчитаем для пары ориентированных ребер (u1, v1) в первом дереве и (u2, v2) во втором дереве значение dp[u1][v1][u2][v2], равное размеру наибольшей пары изоморфных поддеревьев, если вершина u1 перейдет в вершину u2, а вершины v1 и v2 обязательно не войдут в выбранные поддеревья. Кроме того, разрешим vi быть равной какой-нибудь фиктивной вершине -1, это будет значить, что удаленного поддерева vi нет, и можно использовать для общего поддерева все вершины. Если мы посчитаем такую величину, ответом будет максимум по всем парам вершин u1, u2 величины dp[u1][-1][u2][-1].
Чтобы посчитать dp[u1][v1][u2][v2], нужно каким-то образом сопоставить поддеревья u1 и u2 друг другу. Заметим, что если e1 — сын вершины u1, отличный от v1, то поддерево e1 содержит меньше вершин, чем поддерево u1, при подвешивании дерева за v1. Для сыновей e1 вершины u1 и e2 вершины u2 мы по предположению индукции уже посчитали dp[e1][u1][e2][u2], так что мы знаем, сколько вершин можно добавить в искомое поддерево, если вершине e1 в нем будет соответствовать e2. Если у вершины u1 — k сыновей, у u2 — m сыновей, то мы получаем матрицу ai, j размера k·m, в которой нужно выбрать несколько ячеек с максимальной суммой, при условии, что в каждом столбце и в каждой строке выбрано не больше одной ячейки. Это стандартная задача о назначении, которая решается Венгерским алгоритмом.
Итоговая сложность решения — O(n5), n2 способов выбрать пару ребер в двух деревьях и O(n3) — время работы Венгерского алгоритма. Для оптимизации можно не решать задачу о назначении для одинаковых (изоморфных) пар деревьев несколько раз, а запомнить ответ.
Хм, а что значит Accepted по задаче в списке посылок и при этом минус по ней в таблице "Ваши результаты"?
А можете выложить авторское по задаче C (код) и сказать сколько оно работает в тестирующей системе?
UPD: Вопрос с оценкой снимается, см. ниже.
Описанное решение С имеет сложность (по-моему, вы забыли учесть подсчет gcd?). И, как я понял, почти у всех учасников такое решение не заходило в ТЛ без разных бубнов.
gcd массива из n чисел считается за n + O(logMAX), если я все правильно понимаю
Хм, действительно. Никогда раньше не задумывался о том, что у этих операций в сумме такая оценка. Тогда достаточно удивительно, что это с трудом (судя по комментариям в другом посте) заходит в ТЛ.
А можно скачать код своего решения из системы?
http://www.russiancodecup.ru/ru/history/round/51/
спасибо.
Контест будет доступен в тренировках?
добавил контест в тренировки.
Why this solution gets TLE? The complexity is as in the editorial
UPD:On codeforces it pass in ~500 ms but on RCC TLE on test=6
Решения на джаве для C,D полностью соответствующие описанию нифига не проходят по времени. Приходится пропихивать разными левыми способами, мне за время контеста это сделать не удалось. Пожалуйста, дайте авторские решения на Java.
В частности в С можно улучшить до O((a[1]^2/3 + n) * C) где C это константа для GCD вполне очевидным способом: для каждого a[i] посмотреть gcd(a[i],a[1]) = K и запомнить gcd для всех элементов с таким K. Ещё одно улучшение это выбор минимального a[1].
Авторское по D в архиве как раз на Java, емнип
Почему выбор минимального a[1] — это улучшение?
И да, на C++ все тоже не заходило.
У меня решение не заходило по ТЛ, а вот на КФ оно зашло за 530 мс. Решение с эвристическими оптимизациями зашло на RCC, на КФ за 93 мс... Интересно, можно ли на RCC посмотреть время выполнения.
Первый квалификационный раунд добавлен в тренировки!
1st qualification round added to gyms
don't understand the first problem (A)...plz help to solve it.