4 августа 2017 в 11:00 (время московское) открывается первый этап SnarkNews Summer Series 2017. Как и несколько предыдущих серий, SNSS-2017 пройдёт на системе Яндекс.Контест. Опубликовано расписание серии.
По просьбам участников отдельно публикую ссылку для регистрации и входа в первый раунд. В комментариях к этому сообщению по окончании раунда в соответствии с расписанием можно будет обсудить задачи первого раунда.
Как решать D и F?
F: не знаю авторского, но в ТЛ с хорошим запасом заходит квадрат: для каждой длины префикса i перебрать сдвиг второго префикса относительно первого и проверить, равны ли соответствующие подстроки двумя посчитанными z-функциями.
D: пусть фиксировано q (количество максимумов), и массив отсортирован по убыванию. Ответ для q — (считаем вклад каждого элемента, один коэффициент — сколько больших элементов взяли в подпоследовательность, второй — взяли любые из меньших). Если поменять местами порядок суммирования и раскрыть биномиальный коэффициент, то при желании можно увидеть, какие два полинома нужно перемножить фурьешкой, чтобы получить ответ для всех q.
D: Пусть числа a0 ≥ a1 ≥ ... ≥ an - 1. Тогда вклад aj в полную i-ценность коллекции есть (где , если x > y). Получается, что i-ценность коллекции равна . Это префиксные суммы для . Давайте запишем (есть тонкость с j < k, с ней разберёмся попозже). Видим, что . При фиксированном k это уже начинает напоминать свёртку. А именно, посмотрим на "почти многочлены" , (если s > n, то B - s = 0; если s < 0, то B - s = 0, видно, что этого достаточно, чтобы разобраться со случаем k > j). Тогда при фиксированном k это коэффициент произведения этих "многочленов" при xk. Для того, чтобы свести это к произведению настоящих многочленов, просто сдвинем коэффициенты B.
F: в зимнем Петрозаводске 2017 (а также в ГП Гомеля в опенкапе) в этом году была задача "найти позиции минимальных циклических сдвигов для всех префиксов строки". Если мы умеем это делать, то можно просто сравнивать эти минимальные циклические сдвиги хэшами (они равны тогда и только тогда, когда префиксы эквивалентны).
Если я правильно понимаю, то при увеличении длины префикса минимальный циклический сдвиг либо останется тем же, либо переместится на последний символ, так ли это? И если да, то как сравнивать два циклических сдвига при увеличении длины префикса так, чтобы это не вылилось в квадрат?
Хешами с бинпоиском, например.
Найти длину общего префикса и посмотреть на следующий символ?
Да
"Если я правильно понимаю, то при увеличении длины префикса минимальный циклический сдвиг либо останется тем же, либо переместится на последний символ, так ли это?"
Нет. Пусть есть строка
aba
. У неё минимальный сдвиг начинается с третьей позиции. Если дописать к ней символx
, то она станетabax
и её минимальный циклический сдвиг будет начинаться с первой позиции.А можно коротко о том, как всё-таки обновлять циклический сдвиг? Понятно, что если новый символ меньше первого символа текущего минимального сдвига, то новый сдвиг будет начинаться с нового символа, но что делать в остальных случаях?
B, C?
C: Подходит многочлен (x - 1)(x - 2)... (x - n) + x. Надо найти произведение. Это можно сделать в стиле divide and conquer: разделим множители на две части, вычислим ответы для каждой и просто перемножим их. f(n) = 2f(n / 2) + O(n2) даёт f(n) = O(n2). А можно и с FFT, наверное.
B: bitset. Будем идти по возрастанию искомого маршрута и поддерживать для каждой строки два битсета: из каких клеток этой строки можно пойти вправо на k и вниз на k. Из этого логическими операциями и сдвигами можно собрать условие на клетку, может ли она быть центром маршрута, и посчитать количество единичных битов в результате.
С: Так как модуль простой и больше n, то подойдёт (x - 1)(x - 2)... (x - n) + x (совпадает с x в точках 1, 2, ..., n и отличается в n + 1). Перемножать можно просто последовательно за квадрат.
B: Отразим картинку относительно диагонали из левого верхнего угла в правый нижний (это неважно, но мне так проще объяснять). Тогда маршрут сперва идёт вниз, потом вправо, потом опять вниз. Для каждой клетки посчитаем, насколько мы можем отойти вверх, не пересекая водоёмов и края поля и насколько можем отойти вниз (массивы
u
иd
). Каждая строка разбивается на максимальные по включению отрезки, на которых нет водоёмов, будем решать для них независимо. Пусть мы находимся на таком отрезке с l по r в i-той строке. Тога мы хотим выбрать целые числа s и q, что l ≤ s < s + 2q ≤ r, при этомu[i][s] >= q
иd[i][s + 2q] >= q
(соответствует маршруту(i - q, s) -> (i, s) -> (i, s + 2q) -> (i + q, s + 2q)
). Давайте переберём s, тогда q может меняться в пределах от 1 доmin(u[i][s], (r - s) / 2)
и нужно посчитать для скольки q из этого отрезкаd[i][s + 2q] >= q
. Это запрос вида "на отрезке посчитать число позиций, x фиксированной чётности, для которыхd[i][x] - (x / 2) >= -(s / 2)
". Если хранить два дерева отрезков для каждой чётности и перебирать s в порядке возрастания (при этом будут появляться новые хорошие значения x), то получается решение за . У меня без упихивания зашло в дорешку.