Дерево Фенвика для некоммутативных операций
Обычное дерево Фенвика позволяет выполнять некоторую ассоциативную, коммутативную, обратимую операцию на отрезке с изменением элементов. Описываемая модификация дает возможность отказаться от коммутативности .
Обновление элемента
Как и ранее, для обновления элемента в дереве нужно изменить все, что хранит результат операции с этим элементом. Но теперь нельзя просто применить операцию
(далее будем использовать мультипликативную нотацию) ко всем нужным элементам дерева. Пусть мы хотим изменить на , в данный момент обновляем элемент дерева с индексом . Вместо мы получим (так как больше нельзя переставлять элементы местами в операции на отрезке, ответ будет неверен).Решение — нужно удалить отрезок после изменяемого элемента, изменить элемент, после чего добавить этот отрезок снова. Пусть
— результат выполнения операции на префиксе ; — результат ее выполнения на отрезке . Тогда элемент дерева с индексом обновляется как .Доказательство
Может показаться, что этот способ не работает, так как
, возможно, уже было изменено, а — еще нет, значит, мы удаляем не тот отрезок, который должны удалить. Убедимся, что на самом деле все обновляется правильно. Учитывая, что , получаем:;
, то есть элемент дерева изменяется на правильное значение.
Пример
Пусть есть массив из пяти матриц
:
Пусть
— операция умножения матриц. Дерево Фенвика выглядит так:
Пусть теперь
. Значит, надо изменить и .
Время работы
Пусть в дереве
элементов. Так как для каждого из изменяемых элементов дерева мы совершаем дополнительно запрос суммы на отрезке(а он работает за операций), то асимптотическое время работы обновления элемента ухудшается до .Выполнение запроса
Выполнение запроса делается так же, как и в обычном дереве Фенвика, с той лишь разницей, что теперь важен порядок операндов в операции
.