Дан массив arr [0..n-1]. Следующие операции должны быть выполнены.
- update (l, r, val) : добавить 'val' ко всем элементам в массиве из [l, r].
- getRangeSum (l, r) : Найти сумму всех элементов в массиве из [l, r].
Первоначально все элементы в массиве равны 0. Запросы могут быть в любом порядке, т. Е. Перед суммой диапазона может быть много обновлений.
Пример:
Input : n = 5 // {0, 0, 0, 0, 0} Queries: update : l = 0, r = 4, val = 2 update : l = 3, r = 4, val = 3 getRangeSum : l = 2, r = 4 Output: Sum of elements of range [2, 4] is 12 Explanation : Array after first update becomes {2, 2, 2, 2, 2} Array after second update becomes {2, 2, 2, 5, 5}
В предыдущем посте мы обсуждали решения по обновлению диапазона и точечному запросу с использованием BIT.
rangeUpdate (l, r, val): мы добавляем 'val' к элементу с индексом 'l'. Мы вычитаем 'val' из элемента с индексом 'r + 1'.
getElement (index) [или getSum ()]: мы возвращаем сумму элементов от 0 до индекса, который можно быстро получить с помощью BIT.
Мы можем вычислить rangeSum () с помощью запросов getSum ().
rangeSum (l, r) = getSum (r) — getSum (l-1)
Простое решение — использовать решения, обсужденные в предыдущем посте . Запрос на обновление диапазона такой же. Запрос суммы диапазона можно выполнить, выполнив запрос get для всех элементов в диапазоне.
Эффективное решение — убедиться, что оба запроса могут быть выполнены за время O (Log n). Мы получаем сумму диапазона, используя префиксные суммы. Как убедиться, что обновление выполняется таким образом, чтобы сумма префикса могла быть сделана быстро? Рассмотрим ситуацию, когда префикс sum [0, k] (где 0 <= k <n) необходим после обновления диапазона в диапазоне [l, r]. Три случая возникают, так как k может лежать в 3 регионах.
Случай 1 : 0 <k <l
Запрос на обновление не повлияет на запрос суммы.
Случай 2 : l <= k <= r
Рассмотрим пример:
Add 2 to range [2, 4], the resultant array would be: 0 0 2 2 2 If k = 3 Sum from [0, k] = 4
Как получить этот результат?
Просто добавьте val из l- го индекса в k- й индекс. Сумма увеличивается на «val * (k) — val * (l-1)» после запроса на обновление.
Случай 3 : k> r
Для этого случая нам нужно добавить «val» из l- го индекса в r- й индекс. Сумма увеличивается на «val * r — val * (l-1)» из-за запроса на обновление.
Наблюдения:
Случай 1: прост, так как сумма останется такой же, какой была до обновления.
Случай 2: сумма была увеличена на val * k — val * (l-1). Мы можем найти «val», это похоже на поиск i- го элемента в статье обновления диапазона и точечного запроса . Таким образом, мы поддерживаем один бит для обновления диапазона и точечных запросов, этот бит будет полезен при поиске значения по k- му индексу. Теперь вычисляется val * k, как обработать дополнительный термин val * (l-1)?
Чтобы обработать этот дополнительный термин, мы поддерживаем еще один бит (BIT2). Обновите val * (l-1) по l- му индексу, чтобы при выполнении запроса getSum на BIT2 результат получался как val * (l-1).
Случай 3: сумма в случае 3 была увеличена на «val * r — val * (l-1)», значение этого члена можно получить с помощью BIT2. Вместо добавления мы вычитаем «val * (l-1) — val * r», поскольку мы можем получить это значение из BIT2, добавляя val * (l-1), как мы это делали в случае 2, и вычитая val * r в каждом обновлении операция.
Update Query Update(BITree1, l, val) Update(BITree1, r+1, -val) UpdateBIT2(BITree2, l, val*(l-1)) UpdateBIT2(BITree2, r+1, -val*r) Range Sum getSum(BITTree1, k) *k) - getSum(BITTree2, k)
Реализация вышеуказанной идеи
|
Джава
|
C #
|
Выход:
Sum of elements from [1,4] is 50
Сложность времени : O (q * log (n)), где q — количество запросов.
Эта статья предоставлена Чирагом Агарвалом . Если вы как GeeksforGeeks и хотели бы внести свой вклад, вы также можете написать статью с помощью contribute.geeksforgeeks.org или по почте статьи contribute@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.
Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.
Рекомендуемые посты:
- Двоичное индексированное дерево: обновления диапазона и точечные запросы
- Диапазон и обновление суммы запросов с помощью факториала
- Запросы и обновление диапазона значений с помощью квадратного корня
- Запросы на обновление заданного индекса и поиск gcd в диапазоне
- Выполнять запросы добавления, обновления, удаления и суммирования сумм для данного массива
- Сегментное дерево | Установите 2 (Range Maximum Query с обновлением узла)
- Итеративное дерево сегментов (запрос максимального диапазона с обновлением узла)
- Запросы для элементов больше K в заданном диапазоне индекса с использованием дерева сегментов
- Количество элементов больше K в диапазоне от L до R с использованием дерева Фенвика (автономные запросы)
- Массив запросов диапазона над запросами диапазона
- Коэффициент дальности в бинарном дереве
- Индекс k-го установленного бита в двоичном массиве с запросами на обновление
- Разница Массив | Запрос на обновление диапазона в O (1)
- Умножение на массиве: запрос на обновление диапазона в O (1)
- Запрос на диапазон и обновление фигур шахматной доски
0.00 (0%) 0 votes