Доброго времени суток всем. Довольно долго искал в архиве задач и тренировок на Codeforces, но так и не нашел ни одной задачи на двумерное дерево отрезков. Если у кого-нибудь есть на примете пара задач с Codeforces, то будьте добры — поделитесь.
UPD : Вот нашел пару простых задач(последние две), может кому пригодятся.
Может быть лучше и эффективнее будет что-нибудь попроще порешать?
Только это трехмерный Фенвик
Три соревнования — можно решить сжатым двумерным деревом отрезков.
Замечательное решение (Е) — вроде бы решалась квадро-деревом, я не уверен, но может удастся и двумерным деревом отрезков решить.
Я вроде бы ещё несколько видел за последние 1.5 года, но уже не припомню где.
Спасибо.
А может кто скинуть задачу, где += на подматрице и сумма на подматрице?
Вот задача
А не могли бы вы рассказать, как реализовать прибавление на подматрице?
Я знаю как решать эту задачу тремя способами, которые существенно отличаются друг от друга:
2д дерево отрезков с проталкиванием, можно почитать здесь, я этого не писал, потому что скорее всего оно не зайдет из-за большой константы:)
Можно использовать дерево Фенвика, которое умеет прибавлять на отрезке, если почитаете здесь, то я думаю что напишете для одномерного массива, оно легко обобщается на 2д случай(то есть для прямоугольников), правда нужно будет уже 2^2=4 деревьев Фенвика, но зато просто пишется и быстро работает код
Есть еще одно решение, с использованием SQRT-декомпозиции по запросам: Вот предположим есть только запросы увеличения на прямоугольниках, их много, нужно как-то посчитать что получится в конце, можно сделать ее в оффлайне, то есть считать все запросы, а потом что-то сделать, пусть есть прямоугольник (x1, y1, x2, y2, v) нужно каждое число x1 <= x <= x2, y1 <= y <= y2 увеличить на v, как его посчитать в ответе, сделаем дополнительный массив inc, по которому в конце посчитаем частичные суммы, добавим inc[x1][y1] += v; inc[x2 + 1][y1] -= v; inc[x1][y2 + 1] -= v; inc[x2][y2] += v; Частичные суммы считаются за O(nm) если точка (x, y) не входит в прямоугольник (x1, y1, x2, y2) то в частичные суммы не посчитаем, иначе посчитаем, теперь когда мы умеем увеличивать на прямоугольнике в оффлайне, перейдем к решению задачи. Можно считывать запросы по K(выбираем k такое чтобы задача могла пройти:)) штук, и отвечать на каждый запрос за O(K), проходим по всех этих K запросах, если запрос найти сумму, то проходим по всем запросах увеличения, которые в этих K запросах и были раньше находим пересечение данного прямоугольника и того что был раньше, прибавляем к ответу площадь пересечения * на величину и еще прибавляем к ответу, то что в этом прямоугольнике и было раньше до текущих k запросов, на которую нужно было увеличить, и каждые K запросов Rebuildим суммы на прямоугольнике, это будет работать за O(nmq/k+qk), у меня в коде k — это MAGIC
Спасибо за пояснение; я не понял только какую константу вы имели в виду, когда говорили про дерево отрезков.
Такое дерево отрезков работает за Сlog^2n на запрос, и C — в 2д дереве отрезков с проталкиванием большое, почитайте http://habrahabr.ru/post/131072/ — это решение этой же задачи, только с использованием дерева отрезков