В этом листке почти во всех задачах такой сюжет: есть массив данных, организованных в одномерный/двумерный массив или граф.
И есть набор запросов, который предполагает вычисление некоторой функции на отрезке/прямоугольнике.
В худшем случае возможно ещё и изменение данных.
Часто функция обладает таким полезным свойством: ответ множестве X может быть легко вычислен на основе ответа на множестве X∪Y и на множестве Y.
Если предпосчитать достаточно богатый набор значений функции, то потом можно быстро давать ответы.
Пример такой функции — сумма всех элементов множества.
Для подобный функций бывает полезно предпосчитать её значения на всех префиксах или всех суффиксах, или на всех подпрямоугольниках с вершиной в каком-нибудь
угле данных.
Дан массив A длины N, а также M запросов вида lr. Нужно найди произведение элементов массива с l по r по
модулю 109+7.
Гарантируется, что в массиве нет нулей.
Дан двумерный массив A размера N×M, а также Q запросов вида xyx1y1.
Нужно найди сумму элементов подмассива с левым верхним углом в (x,y) и правым нижним (x1,y1)
Вообще, идея префиксных предподсчетов довольно часто возникает в программировании, но у данного
подхода есть как плюсы (например, ответ за O(1)), так и минусы, например, изменение элементов
происходит за O(n), что очень долго.
Научимся за не слишком медленно изменять элементы, не сильно замедлив процедуру ответа.
Идея несколько похожа на идею префиксного подсчета: давайте поделим весь массив на блоки размера k,
в каждом из которых посчитаем ответ и запишем в массив blocks.
Теперь научимся получать ответ. Пусть есть запрос на вычисление функции на отрезке с l по r.
Выделим внутри этого отрезка полные блоки, и добавим их в ответ, а "хвост" обработаем руками.
Суммарная ассимптотика O(n/k+k). Оказывается, самым оптимальным значением для k есть n
Теперь заметим, что изменение работает за O(1). Изменив элемент и ответ в соответствующем блоке мы
полностью обновим структуру.
Дан массив A длины N, а также M запросов одного из 2х видов:
сумма на отрезке
инкремент на отрезке
Требуется ответить на все запросы суммы на отрезке
5 3
1 2 3 4 5
1 1 5
2 2 5 3
1 1 5
15
27
Подсказка
Да что-то непонятное тут требуют...
Храни вспомогательный массив для блоков.
Тут какая-то жесть
Давате хранить вспомогательный массив add длиной n в каждой ячейке которого будем
хранить насколько суммарно мы увеличили все числа в данном блоке. Теперь обновление выглядит так:
ищем "цельные" блоки, увеличиваем суммарный инкремент, а "хвост" обрабатываем руками.
IDE
# Хранение дополнительной информации в декомпозиции
Часто, бывает удобно хранить вспомогательную структуру внутри декомпозиции, например, массив инкрементов
на блоках. В следующих задачах вам предстоит самим догадаться, какие именно доп.структуры надо использовать.
IDE
H: Количество чисел меньших k с инкрементом на отрезке
Для заданного массива требуется выполнить ряд запросов. Все запросы делятся на два типа. Запрос первого типа – вычислить
количество элементов массива на отрезке от l до r меньших заданного числа x. Запрос второго типа – увеличить все
элементы массива на отрезке от l до r на заданное число x.
1 - найти количество чисел меньших k и больших l на отрезке
2 - инкремент на отрезке на величину x
Требуется ответить на все запросы.
5 3
1 2 3 4 5
1 1 5 5
2 2 4 2
1 1 5 5
4
2
IDE
I: K-я порядковая статистика на отрезке с изменением на отрезке
Для заданного массива требуется выполнить ряд запросов. Все запросы делятся на два типа.
Вычислить k-тую порядковую статистику на отрезке с l по r.
Увеличить все элементы массива на отрезке от l до r на заданное число x.
В задачах на запросы на графах иногда работает следующий трюк: разделим вершины на "тяжелые" и "лёгкие" по следующему
принципу:
тяжелыми будут вершины со степенью больше или равные E, а легкими все остальные.
Тогда для тяжелых вершин будем хранить ответ явно, а для легких будем считать ответ "ручками".
Так как тяжелых вершин не больше E, и степень легких не больше E, то суммарная ассимптотика решения -
O(VE)
Вам дан граф с N вершинами и M ребрами. У каждой вершины есть свой цвет vi. Вам дано q запросов в виде пары
(vi,ci),
означающий, что надо перекрасить вершину vi в цвет ci. После каждого запроса нужно вывести количество ребер у
которых вершины покрашены в разный цвет.
Дан неориентированный граф без петель и кратных ребер, у которого n вершин и m ребер.
У каждой вершины есть цвет. Требуется ответить на q запросов. Каждый запрос имеет один из двух типов:
vc – перекрасить вершину v в цвет c
v – вычислить количество различных цветов у соседей вершины v.
Назовем строку S длинной, если ∣S∣≥∑∣S∣. Все оставшиеся строки назовем легкими.
Утверждение. Существует не более 2∑∣S∣ тяжелых строк.
Доказательство. Пусть существуют более 2∑∣S∣. Тогда их суммарная длина больше, чем
22∑∣S∣∑∣S∣=∑∣S∣, что противоречит условию.
Утверждение. Существует не более O(∑∣S∣) различных длин.
Доказательство. Пусть оно равно x. Тогда минимально возможная сумма длин - это сумма чисел от 1 до x.
∑1x=2x(x+1). Так как это число должно быть меньше, чем ∑∣S∣, то x=O(∑∣S∣)
У Пупы есть n строк S1,S2,S3,...,Sn Однажды его друг Лупа пришёл в бухгалтерию и попросил
его ответить на q вопросов: сколько строк среди Sli,Sli+1,Sli+2,...,Sr содержат Pi как
подстроку?
Но в бухгалтерии все перепутали, и ответить на запросы за Пупу придется Вам.
Некоторые запросы обновления можно легко обрабатывать группой, например сделав scanline, но тяжело обрабатывать по одному.
В таких случаях можно откладывать их выполнение, и запоминать их в какой-нибудь список. При размере списка
O(n) можно обработать все запросы этого списка группой. При выполнении get-запросов достаточно смотреть на все
запросы внутри списка и смотреть, как они влияют на ответ
Малыш и Карлсон решили пойти на прогулку. Они знают, что прогулка будет совсем скучной, если перед ней не опустошить
несколько банок варенья.
Малыш достал из кладовки N банок варенья и выставил их в ряд. В банке номер i содержится ровно a i грамм варенья.
Карлсон немного подумал и решил, что в некоторых банках недостаточно варенья, и что в банке номер i должно быть хотя
бы bi грамм варенья.
Выходить из этой ситуации Карлсон хочет в M этапов. На каждом этапе он выбирает числа l, r, x и y,
а затем выполняет следующие операции: в банку номер l он добавляет x грамм варенья, в банку номер l+1 — x+y
грамм варенья, в банку номер l+2 — x+2⋅y, и так далее.
В банку номер r наш герой добавит x+y⋅(r−l) грамм варенья.
Малышу хочется определить для каждой банки i наименьший номер операции, после которой в ней станет хотя бы b i грамм
варенья. Помогите Малышу: найдите соответствующее число для каждой банки.
В первой строке входного файла задано одно число N(1≤n≤105) — количество банок. Во второй строке заданы N
чисел ai(0≤ai≤2⋅109) — изначальное количество варенья в банке номер i. В третьей строке заданы N чисел
bi(0≤bi≤2⋅109) — минимальное количество варенья, которое должно быть в банке номер i.
В четвертой строке задано M(0≤M≤105) — число этапов добавления варенья в банки, которые выполнит Карлсон. В
следующих M строках описаны сами этапы в хронологическом порядке. Каждый этап задан четырьмя числами l, r, x и
y(1≤l≤r≤N,0≤x,y≤105).
Выходные данные
Выведите N чисел в одной строке, разделенные пробелом. Число номер i должно быть равно нулю, если в банке номер i
изначально было достаточно варенья, номеру этапа, после которого в ней станет хотя бы bi варенья, или −1, если
даже после выполнения всех этапов, в этой банке будет недостаточно варенья. Этапы нумеруются с единицы.
Пусть есть задача на массиве, которую, которую мы умеем решать без запросов обновления, в offline. Запросы могут быть
любой степени ужасности, если мы умеем на них отвечать структурой данных, которая хранит информацию об отрезке [l,r]
и поддерживает следующие операции:
add_left
add_right
del_left
del_right
query
, которые меняют границы отрезка и внтуреннею структуру данных, а так же позволяют сделать запрос. Все запросы мы
пересортируем по паре (⌊l⌋,r).
Отвечать на запрос мы будем таким образом: с помощью реализованных операций изменим необходимые нам границы отрезка,
после чего вызовем запрос query.
Заметим, что левые границы разбиваются по блокам, внутри блока правые границы отсортированы. При переходе от запроса к
запросу, левая граница делает O(n) сдвигов. Правая же граница для запросов одного блока сделает
суммарно не более O(n). Так как общее число блоков O(n), то и суммарное время работы
составляет O(nn)
Имеется список из n юнг, для каждого из которых известен его рост a1,a2,a3,...,an. Рассмотрим некоторый его
подсписок al,al+1,al+2,...,ar, где 1≤l≤r≤n, и для каждого натурального числа s обозначим через
Ks число юнг с ростом s в этом подсписке. Назовем мощностью подсписка сумму произведений Ks⋅Ks⋅s по всем различным натуральным s. Так как количество различных чисел в массиве конечно, сумма содержит лишь
конечное число ненулевых слагаемых.
Необходимо вычислить мощности каждого из t заданных подсписков.
Формат входных данных
Первая строка содержит два целых числа n и t(1≤n,t≤200000) — длина списка и количество
запросов соответственно.
Вторая строка содержит n натуральных чисел ai(1≤ai≤106) — рост юнг.
Следующие t строк содержат по два натуральных числа l и r(1≤l≤r≤n) — индексы левого
и правого концов соответствующего подсписка.
Формат выходных данных
Выведите t строк, где i-ая строка содержит единственное натуральное число — мощность подсписка i-го запроса
Дана перестановка из n элементов.
Ответьте на m запросов про число инверсий для подотрезка перестановки от l до r.
Инверсией называется пара индексов i,j такая, что i<j и ai>aj , где ai - это i-ый элемент
перестановки.
Формат входных данных
В первой строке задано число n(1≤n≤105).
Во второй строке задана перестановка из n элементов (элементы перестановки — попарно различные целые числа от 1 до n).
В третьей строке задано число m(1≤m≤105).
В последующих m строках содержится по два числа, l и r, границы запроса (1≤l,r≤n).
Дано дерево, на каждом ребре которого написано неотрицательное целое число. Вам необходимо
ответить на несколько запросов вида «для данных вершин u, v назовите наименьшее неотрицательное целое число, которое не встречается среди чисел, написанных на ребрах на пути от u до
v».
Входные данные
Первая строка входных данных содержит два числа n и q (1≤n,q≤3∗105), количество
вершин и количество запросов.
Следующие n−1 строк содержат по три числа ui ,vi, xi (1≤ui,vi≤n;0≤xi≤109)
которые описывают ребро дерева (ui, vi), на котором написано число xi.
Следующие q строк содержат по паре чисел aj, bj, которая обозначает запрос на
пути от aj до bj
Выходные данные
Для каждого запроса выведите единственное число — минимальное неотрицательное число, которое не встречается на пути.
Диме не дарили массив a, состоящий из n целых чисел на день рождения, он не покупал его, не
находил на улице, а он у него просто есть и всегда был, и Диме не очень-то и интересно откуда.
Дима не играет с массивом, не дарит его Пете, не режет на кусочки и не стремится его уничтожить. Дима просто выполняет операции двух видов со своим массивом:
MEX мультимножества чисел {a1,a2,...,ak} — это минимальное целое t≥0 такое, что t=ai для
всех 1≤i≤k.
На самом деле, Диме не очень нравится выполнять операции двух видов со своим массивом.
Диму волнуют лишь результаты операций первого типа. Помогите Диме и напишите программу,
которая выполнит операции за него.
Формат входных данных
Первая строка содержит два целых числа n и q(1≤n≤500000,1≤q≤250000) — размер
массива, который есть у Димы и количество операций, соответственно.
Вторая строка содержит n целых чисел ai(0≤ai≤n) — массив Димы до начала операций.
Каждая из следующих q строк содержит описание одной операции в формате, описанном выше.
Элементы массива пронумерованы, начиная с 1.
Формат выходных данных
Для каждой операцияя первого типа выведите одно целое число — MEX соответствующего мультимножества. Ответы на запросы выводите в порядке, в котором они заданы во входных данных.
На курсе машинного обучения вам выдали первое домашнее задание — вам предстоит проанализировать некоторый массив из n чисел.
В частности, вы интересуетесь так называемой равномерностью массива. Предположим, что в массиве число b1 встречается k1 раз,
b2 - k2 раз, и т.д. Тогда равномерностью массива называется такое минимальное целое число c≥1, что c=ki для любого i.
В рамках вашего исследования вы хотите последовательно проделать q операций.
Операция ti=1, li, ri задаёт запрос исследования. Необходимо вывести равномерность массива, состоящего из элементов на позициях от li до ri включительно.
Операция ti=2, pi, xi задаёт запрос уточнения данных. Начиная с этого момента времени pi-му элементу массива присваивается значения xi.
Входные данные
Первая строка содержит n и q — размер массива и число запросов соответственно.
Во второй строке записаны ровно n чисел — a1,a2,...,an (1≤ai≤109).
Каждая из оставшихся q строк задаёт очередной запрос.
Запрос первого типа задаётся тремя числами ti=1, li, ri, где 1≤li≤ri≤n — границы соответствующего отрезка.
Запрос второго типа задаётся тремя числами ti=2, pi, xi, где 1≤pi≤n — позиция в которой нужно заменить число, а 1≤xi≤109 — его новое значение
Выходные данные
Для каждого запроса первого типа выведите одно число — равномерность соответствующего отрезка массива.