Сведение задачи RMQ к задаче LCA — различия между версиями
Строка 12: | Строка 12: | ||
* Любая вершина дерева всегда имеет меньшее значение, чем её дети. Тогда любой предок <tex>A[i]</tex> или <tex>A[j]</tex> меньше их самих. | * Любая вершина дерева всегда имеет меньшее значение, чем её дети. Тогда любой предок <tex>A[i]</tex> или <tex>A[j]</tex> меньше их самих. | ||
* <tex>LCA(A[i], A[j])</tex> ближайший к корню и по п.1 имеет наименьшее значение в своем поддереве. По построению, это поддерево содержит в частности подмассив <tex>A[i..j], </tex> и <tex>LCA(A[i], A[j])</tex> находится между <tex>A[i]</tex> и <tex>A[j]</tex>. То есть <tex>LCA(A[i], A[j])</tex> является <tex>RMQ(i, j).</tex> | * <tex>LCA(A[i], A[j])</tex> ближайший к корню и по п.1 имеет наименьшее значение в своем поддереве. По построению, это поддерево содержит в частности подмассив <tex>A[i..j], </tex> и <tex>LCA(A[i], A[j])</tex> находится между <tex>A[i]</tex> и <tex>A[j]</tex>. То есть <tex>LCA(A[i], A[j])</tex> является <tex>RMQ(i, j).</tex> | ||
+ | == Построение дерева за линейное время == | ||
+ | Пусть дан массив <tex>A[1..N]</tex>. Будем по очереди слева на право добавлять элементы в дерево. Чтобы добавить новое значение <tex>A[i]</tex>, начнем обход из вершины <tex>A[i-1]</tex> к корню, пока не найдем вершину <tex>x</tex>, для которой <tex>x < A[i]</tex>. Тогда правого сына <tex>x</tex> назначим левым сыном <tex>A[i]</tex>, а <tex>A[i]</tex> {{---}} правым сыном <tex>x</tex>. Рассмотрим правую ветку дерева, т.е. по которой проходит обход алгоритма. Заметим, что при добавлении нового узла в дерево элементы, по которым только что прошелся алгоритм отправляются налево, т.е. перестают принадлежать правой ветке. Таким образом процедура поиска родителя не сможет выполнится более <tex>n</tex> раз и итоговая асимптотика алгоритма <tex>O(n)</tex>. | ||
== Сложность == | == Сложность == | ||
− | + | Выше описан алгоритм построения дерева за <tex>O(n)</tex>. | |
− | |||
Препроцессинг для <tex>LCA</tex> {{---}} <tex>O(n)</tex> и ответ на запрос <tex>O(1)</tex>. | Препроцессинг для <tex>LCA</tex> {{---}} <tex>O(n)</tex> и ответ на запрос <tex>O(1)</tex>. | ||
В итоге получили <tex>RMQ</tex> {построение <tex>O(n)</tex>, запрос <tex>O(1)</tex>}. | В итоге получили <tex>RMQ</tex> {построение <tex>O(n)</tex>, запрос <tex>O(1)</tex>}. | ||
== См.также == | == См.также == | ||
*[[Сведение задачи LCA к задаче RMQ]] | *[[Сведение задачи LCA к задаче RMQ]] | ||
+ | ==Ссылки== | ||
+ | *[[http://e-maxx.ru/algo/rmq_linear|Задача RMQ. Решение за O (1) с препроцессингом O (N)]] |
Версия 17:04, 8 апреля 2012
Содержание
Постановка задачи RMQ
Дан массив
. Поступают запросы вида , на каждый запрос требуется найти минимум в массиве , начиная с позиции и заканчивая позицией .Алгоритм
Декартово дерево (англ. сartesian tree) на массиве
— это бинарное дерево, рекурсивно определенное следующим образом:- Корнем дерева является минимальное значение в массиве , скажем . Если минимальных значений несколько, можно взять любое.
- Левым поддеревом является декартово дерево на массиве .
- Правым поддеревом является декартово дерево на массиве .
Построим декартово дерево на массиве
. Тогда = .Доказательство
Мы знаем что:
- Любая вершина дерева всегда имеет меньшее значение, чем её дети. Тогда любой предок или меньше их самих.
- ближайший к корню и по п.1 имеет наименьшее значение в своем поддереве. По построению, это поддерево содержит в частности подмассив и находится между и . То есть является
Построение дерева за линейное время
Пусть дан массив
. Будем по очереди слева на право добавлять элементы в дерево. Чтобы добавить новое значение , начнем обход из вершины к корню, пока не найдем вершину , для которой . Тогда правого сына назначим левым сыном , а — правым сыном . Рассмотрим правую ветку дерева, т.е. по которой проходит обход алгоритма. Заметим, что при добавлении нового узла в дерево элементы, по которым только что прошелся алгоритм отправляются налево, т.е. перестают принадлежать правой ветке. Таким образом процедура поиска родителя не сможет выполнится более раз и итоговая асимптотика алгоритма .Сложность
Выше описан алгоритм построения дерева за
. Препроцессинг для — и ответ на запрос . В итоге получили {построение , запрос }.