Сегодняшний пост посвящен задаче E из последнего раунда Codeforces Round 1078 (Div. 2), а именно тому, как же до неё додуматься.
Предупреждение: Все индексы в этом посте написаны в привычной для кодера 0-нумерации, вместо привычной для обычного человека 1-нумерации.
Все мы знаем, как решается задача о черепашке. Пусть дана таблица $$$n \times m$$$, в каждой клетке записаны числа $$${a_i}_j$$$. Черепашка может ходить только вниз или вправо на одну клетку, то есть из клетки $$$(i, j)$$$ в клетки $$$(i + 1, j)$$$, $$$(i, j + 1)$$$. Награда черепашки при прохождении от клетки $$$(0, 0)$$$ до клетки $$$(n - 1, m - 1)$$$ определяется как сумма значений $$${a_i}_j$$$ во всех клетках, которые она посетила. Требуется найти максимальную награду, которую может получить черепашка.
Такая задача решается за $$$O(n \cdot m)$$$ и решение находит награду максимального пути от клетки $$$(0, 0)$$$ до каждой клетки $$$(i, j)$$$.
Если же Вы не знаете решение такой задачи, рекомендуется сначала его придумать или прочитать на просторах интернета.
В этой же задаче Рафаэль сначала изменяет значение ровно одной клетки на противоположное, после чего Микеланджело решает задачу о черепашке и максимизирует свою награду. Требуется посчитать какую минимальную награду может гарантировать Рафаэль. Ограничения: $$$n \cdot m \leq 10^5$$$
Вопрос 1: как решать эту задачу за любую асимптотику?
Подсказка 1.1Достаточно даже решения, например, за $$$O(n^2 \cdot m^2)$$$
Ответ 1.1Можно явным образом поменять каждый элемент матрицы $$$a$$$ на противоположный и для каждой замены решить задачу о черепашке. Замен будет $$$n \cdot m$$$, одна черепашка решается за $$$O(n \cdot m)$$$, итого решение за $$$O(n^2 \cdot m^2)$$$
К сожалению, совсем наивного решения не хватает, чтобы решение работало меньше секунды. С другой стороны, так как в таблице меняется только лишь одна клетка, мы можем надеяться на то, что ответ в задаче про черепашку поменяется не сильно
Вопрос 2: как посчитать ответ на задачу о черепашке, если изменить значение в одной клетке?
Подсказка 2.1Если в задаче о черепашке мы ищем путь с максимальной наградой, логично задуматься, награды каких путей меняются, а каких нет?
Ответ 2.1Если мы изменим значение в клетке $$$(i, j)$$$, то изменятся только награды тех путей, которые проходят через клетку $$$(i, j)$$$. Также несложно понять, что награда каждого такого пути уменьшится на $$$2 \cdot {a_i}_j$$$ по сравнению с изначальной задачей
Подсказка 2.2Теперь мы поняли, что нам достаточно посчитать максимальный по награде путь, проходящий через клетку $$$(i, j)$$$ и максимальный по награде путь, не проходящий через неё. Но, так как такие значения придётся считать для каждой клетки, нужно это делать быстро. Начнём с простого: как посчитать максимальный путь из $$$(0, 0)$$$ в $$$(n - 1, m - 1)$$$, проходящий через $$$(i, j)$$$?
Ответ 2.2Любой такой путь разбивается на два пути — из $$$(0, 0)$$$ в $$$(i, j)$$$ и из $$$(i, j)$$$ в $$$(n - 1, m - 1)$$$, поэтому нам нужно посчитать максимальный путь из $$$(0, 0)$$$ в $$$(i, j)$$$ и максимальный путь из $$$(i, j)$$$ в $$$(n - 1, m - 1)$$$ по-отдельности, сложить и вычесть $$${a_i}_j$$$ (так как мы учли это значение как награду обоих путей. Нам повезло, что в задаче о черепашке мы считаем максимальную награду пути от $$$(0, 0)$$$ до всех клеток $$$(i, j)$$$ разом! Давайте тогда запустим две черепашки — одну из клетки $$$(0, 0)$$$ и назовём её $$$turtle1$$$. То есть $$${turtle_i}_j$$$ будет максимальной наградой пути из $$$(0, 0)$$$ до $$$(i, j)$$$. Вторую же черепашку запустим из клетки $$$(n - 1, m - 1)$$$ с возможностью ходить только вверх и влево и назовём её $$$turtle2$$$. Таким образом, $$${turtle2_i}_j$$$ будет равно максимальной награде пути из $$$(n - 1, m - 1)$$$ в $$$(i, j)$$$, что равно максимальной награде пути из $$$(i, j)$$$ в $$$(n - 1, m - 1)$$$
Теперь мы можем выразить интересующую нас величину как $$${turtle1_i}_j + {turtle2_i}_j - {a_i}_j$$$
Подсказка 2.3Нам осталось лишь посчитать награду максимального пути, не проходящего через клетку $$$(i, j)$$$. Давайте подумаем, можно ли это значение выразить через длины путей, проходящих через какие-то другие клетки доски?
Ответ 2.3Оказывается, что можно. Давайте заметим, что путь не может проходить одновременно через клетку $$$(i, j)$$$ и через клетки, которые находятся слева снизу или справа сверху от неё. Такие клетки выделены на рисунке ниже

Тогда нам достаточно посчитать максимальную награду пути, проходящую через одну из таких клеток.
Но этих клеток очень много! Поэтому давайте сократим множество до диагонали? Путь черепашки проходит через ровно одну клетку диагонали, поэтому, если он не проходит через $$$(i, j)$$$, то проходит через одну из остальных клеток!

Это значит, что максимальный путь, не проходящий через $$$(i, j)$$$ — это максимум из максимальных путей, проходящих через другие клетки той же диагонали.
Из прошлых пунктов мы знаем, как посчитать ответ на задачу для изменения каждой клетки. Остался лишь последний рывок:
Вопрос 3: как посчитать ответ для изменения каждой клетки за $$$O(n \cdot m)$$$ суммарно?
Подсказка 3.1Давайте посчитаем ответ для каждой диагонали отдельно за $$$O(L)$$$, где $$$L$$$ — это длина диагонали. Чтобы понять, как прийти к такому решению, попробуйте выразить ответ для одной клетки диагонали формулой
Ответ 3.1Как и было сказано, давайте выразим ответ понятной формулой. Пускай $$$(i, j)$$$ — самая нижняя клетка данной диагонали, тогда все клетки диагонали имеют координаты $$$(i - d, j + d)$$$, где $$$0 \leq d \lt L$$$. Обозначим за $$$f_d$$$ награду наибольшего пути, проходящего через $$$(i - d, j + d)$$$. Мы знаем, что $$$f_d = {turtle1_{i-d,}}_{j+d} + {turtle2_{i-d,}}_{j+d} - {a_{i-d,}}_{j+d}$$$. Как было замечено, награда наибольшего пути, не проходящего через $$$(i - d, j + d)$$$ равна $$$\max\limits_{0 \leq t \lt L, t \neq d} f_t$$$, или, что то же самое, $$$max(\max\limits_{0 \leq t \lt d} f_t, \max\limits_{t + 1 \leq t \lt L} f_t)$$$, то есть максимум на префиксе и суффиксе. А для вычисления ответа необходимо также взять максимум полученного значения с максимальным путём, проходящим через клетку $$$(i - d, j + d)$$$, что равно $$$f_d - 2 \cdot {a_{i - d,}}_{j + d}$$$
Имея перед глазами формулу в таком виде, несложно догадаться, что нам достаточно посчитать префиксные и суффиксные максимумы из значений $$$f_d$$$, чтобы посчитать ответ в каждой точке за $$$O(1)$$$.
Итого, мы за $$$O(n \cdot m)$$$ времени и памяти суммарно научились получать ответ на все $$$n \cdot m$$$ задач о черепашке, в каждой из которых изменился знак значения одной из клеток. Теперь давайте возьмём минимум из всех полученных значений — это и будет ответом на задачу.
Замечание: Если Вам понравился это пост, то, возможно, Вам понравится контент из телеграм канала, в который я выкладываю свою подготовку к финалу ICPC 2026. Переходите по ссылке