Дан массив arr [0. , , н-1]. Найти максимум элементов от индекса l до r, где 0 <= l <= r <= n-1. Кроме того, измените значение указанного элемента массива на новое значение x. Нам нужно сделать arr [i] = x, где 0 <= i <= n-1, а затем найти максимальный элемент данного диапазона с обновленными значениями.
Пример :
Input : {1, 3, 5, 7, 9, 11} Maximum Query : L = 1, R = 3 update : set arr[1] = 8 Output : Max of values in given range = 7 Updated max of values in given range = 8
Простое решение — запустить цикл от l до r и вычислить максимум элементов в заданном диапазоне. Чтобы обновить значение, просто сделайте arr [i] = x. Первая операция занимает время O (n), а вторая операция занимает время O (1).
Эффективный подход. Здесь нам необходимо выполнить операции за O (Logn), чтобы мы могли использовать дерево сегментов для выполнения обеих операций за O (Logn) .
Представление Сегментных деревьев
1. Конечные узлы являются элементами входного массива.
2. Каждый внутренний узел представляет максимум всех своих дочерних узлов.
Представление массива дерева используется для представления деревьев сегментов. Для каждого узла в индексе i левый дочерний элемент находится в индексе 2 * i + 1 , правый дочерний элемент — в индексе 2 * i + 2, а родительский элемент — в индексе (i-1) / 2 .
Построение дерева сегментов из заданного массива:
Начнем с сегмента arr [0. , , n-1], и каждый раз, когда мы делим текущий сегмент на две половины (если он еще не стал сегментом длины 1), а затем вызываем одну и ту же процедуру для обеих половин, и для каждого такого сегмента мы сохраняем максимум значение в сегменте дерева узла. Все уровни построенного дерева сегментов будут полностью заполнены, кроме последнего уровня. Кроме того, дерево будет полным двоичным деревом, потому что мы всегда делим сегменты на две половины на каждом уровне. Поскольку построенное дерево всегда является полным двоичным деревом с n листьями, будет иметься n-1 внутренних узлов. Таким образом, общее количество узлов будет 2 * n — 1 . Высота сегмента дерева будет log2n . Поскольку дерево представлено с использованием массива и необходимо поддерживать связь между родительскими и дочерними индексами, объем памяти, выделенной для дерева сегментов, будет 2 * (2 ^ ceil (log2n)) — 1 .
Запрос минимального значения заданного диапазона . После того как дерево построено, ниже приведен алгоритм поиска максимума заданного диапазона.
node--> node number, l --> query start index, r --> query end index; int getMax(node, l, r) { if range of node is within l and r return value of node else if range of node is completely outside l and r return -1 else return max(getMax(node's left child, l, r), getMax(node's right child, l, r)) }
Ниже приведена реализация вышеуказанного подхода:
|
Выход:
Max of values in given range = 7 Updated max of values in given range = 8
Рекомендуемые посты:
- Итеративное дерево сегментов (запрос максимального диапазона с обновлением узла)
- Сегментное дерево | Set 2 (Range Minimum Query)
- Итеративное дерево сегментов (минимальный диапазон запросов)
- Разница Массив | Запрос на обновление диапазона в O (1)
- Запрос на диапазон и обновление фигур шахматной доски
- Умножение на массиве: запрос на обновление диапазона в O (1)
- Двоичное индексированное дерево: обновление диапазона и запросы диапазона
- Сегментное дерево | Набор 1 (сумма заданного диапазона)
- Сегментное дерево | (XOR заданного диапазона)
- Сегментное дерево | Набор 3 (XOR заданного диапазона)
- Максимальный диапазон запроса с использованием Sparse Table
- Запросы для элементов больше K в заданном диапазоне индекса с использованием дерева сегментов
- Диапазон и обновление суммы запросов с помощью факториала
- Запросы и обновление диапазона значений с помощью квадратного корня
- Запросы на обновление заданного индекса и поиск gcd в диапазоне
0.00 (0%) 0 votes