Итак, я прочитал это руководство TopCoder по RMQ (запрос минимального диапазона), и у меня возник большой вопрос.
В разделе, где он представил подход, что я могу понять до сих пор, так это:
(Фактически весь подход использует методологию, представленную в Sparse Table ( ST) Алгоритм, Переход с LCA на RMQ и от RMQ до LCA)
Учитывая массив A[N], нам нужно преобразовать его в декартово дерево, таким образом сделав проблему RMQ проблемой LCA (наименьший общий предок). Позже мы можем получить упрощенную версию массива A и сделать ее ограниченной задачей RMQ.
Так что это в основном два преобразования. Таким образом, первая часть RMQ для LCA проста. Используя стек, мы можем выполнить преобразование за время O(n), в результате чего получится массив T[N], где T[i] — родительский элемент i. И дерево готово.
Но вот чего я не могу понять. Для подхода O(n) требуется массив, где |A[i] - A[i-1]| = 1
, и этот массив представлен в Сокращение от LCA до RMQ раздела руководства. Это включает Эйлеровский тур по этому дереву. Но как этого добиться с моим конечным результатом преобразования? Мой подход к этому не является линейным, поэтому в этом подходе его следует считать плохим, каким будет для этого линейный подход?
ОБНОВЛЕНИЕ: момент, который меня смущает
Here's the array A[]:
n : 0 1 2 3 4 5 6 7 8 9
A[n]: 2 4 3 1 6 7 8 9 1 7
Here's the array T[]:
n : 0 1 2 3 4 5 6 7 8 9
T[n]: 3 2 0 * 8 4 5 6 3 8 // * denotes -1, which is the root of the tree
//Above is from RMQ to LCA, it's from LCA to RMQ part that confuses me, more below.
Изображение дерева:
Euler Tour должен знать дочерний элемент каждого узла, точно так же, как DFS (поиск в глубину), в то время как T [n] имеет только корень каждого элемента, а не дочерний элемент.