Ответ 1
Вот мое настоящее понимание того, что вас смущает:
- Чтобы уменьшить RMQ до LCA, вам нужно преобразовать массив в дерево, а затем выполнить тур Euler по этому дереву.
- Чтобы совершить тур Euler, вам нужно сохранить дерево таким образом, чтобы каждый node указывал на его дочерние элементы.
- Редукция, указанная в RMQ для LCA, имеет каждый node пункт родителя, а не его дочерних элементов.
Если это так, ваши проблемы полностью оправданы, но есть простой способ исправить это. В частности, если у вас есть массив всех указателей родительских элементов, вы можете преобразовать их в дерево, где каждый node указывает своим дочерним элементам в O (n) время. Идея такова:
- Создать массив из n узлов. Каждый node имеет поле значений, левый дочерний элемент и правый дочерний элемент.
- Сначала установите nth node, чтобы иметь нулевой левый дочерний элемент, нулевой правый дочерний элемент и значение n-го элемента из массива.
- Итерации по массиву T (где T [n] является родительским индексом n) и выполните следующие действия:
- Если T [n] = *, то n-я запись является корнем. Вы можете сохранить это для последующего использования.
- В противном случае, если T [n] n, то вы знаете, что node n должен быть правильным дочерним элементом его родителя, который хранится в позиции T [n]. Поэтому установите для правильного ребенка T [n] th node значение nth node.
- В противном случае, если T [n] > n, то вы знаете, что node n должен быть левым дочерним элементом его родителя, который хранится в позиции T [n]. Поэтому установите левый дочерний элемент T [n] th node равным nth node.
Это выполняется во времени O (n), так как каждый node обрабатывается ровно один раз.
Как только это будет сделано, вы явно сконструировали древовидную структуру, которая вам нужна, и указатель на корень. Оттуда должно быть достаточно просто продолжить работу с остальной частью алгоритма.
Надеюсь, это поможет!