Дерево Фенвика для некоммутативных операций — различия между версиями
(→Обновление элемента) |
(→Обновление элемента) |
||
| Строка 3: | Строка 3: | ||
== Обновление элемента == | == Обновление элемента == | ||
| − | Как и ранее, для обновления элемента в дереве нужно изменить все, что хранит результат операции с этим элементом. Но теперь нельзя просто применить операцию <tex> G </tex> (далее будем использовать мультипликативную нотацию) ко всем нужным элементам дерева. Пусть мы хотим изменить <tex> a_i </tex> на <tex> a_i' = a_i \cdot d </tex>, в данный момент обновляем элемент дерева с индексом <tex> j </tex>. Вместо <tex> a_{j \& (j + 1)} \cdot \ldots a_i | + | Как и ранее, для обновления элемента в дереве нужно изменить все, что хранит результат операции с этим элементом. Но теперь нельзя просто применить операцию <tex> G </tex> (далее будем использовать мультипликативную нотацию) ко всем нужным элементам дерева. Пусть мы хотим изменить <tex> a_i </tex> на <tex> a_i' = a_i \cdot d </tex>, в данный момент обновляем элемент дерева с индексом <tex> j </tex>. Вместо <tex> a_{j \& (j + 1)} \cdot \ldots a_i \cdot d \cdot \cdot \ldots \cdot a_j </tex> мы получим <tex> a_{j \& (j + 1)} \cdot \ldots a_i \cdot \ldots \cdot a_j \cdot d </tex> (так как больше нельзя переставлять элементы местами в операции на отрезке, ответ будет неверен). |
Решение — нужно удалить отрезок после изменяемого элемента, изменить элемент, после чего добавить этот отрезок снова. Пусть <tex> s_i = a_1 \cdot a_2 \cdot \ldots \cdot a_i </tex> — результат выполнения операции на префиксе <tex> i </tex>; <tex> s_{i, j} = s_i^{-1} \cdot s_j </tex> — результат ее выполнения на отрезке <tex> [i; j] </tex>. Тогда элемент дерева с индексом <tex> j </tex> обновляется как <tex> t_j' = t_j \cdot s_{i, j}^{-1} \cdot d \cdot s_{i, j} </tex>. | Решение — нужно удалить отрезок после изменяемого элемента, изменить элемент, после чего добавить этот отрезок снова. Пусть <tex> s_i = a_1 \cdot a_2 \cdot \ldots \cdot a_i </tex> — результат выполнения операции на префиксе <tex> i </tex>; <tex> s_{i, j} = s_i^{-1} \cdot s_j </tex> — результат ее выполнения на отрезке <tex> [i; j] </tex>. Тогда элемент дерева с индексом <tex> j </tex> обновляется как <tex> t_j' = t_j \cdot s_{i, j}^{-1} \cdot d \cdot s_{i, j} </tex>. | ||
| Строка 39: | Строка 39: | ||
Пусть теперь <tex> a_2 = a_2 \cdot d = \begin{pmatrix} 0 & 1 \\ 2 & 0 \end{pmatrix} \cdot \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} </tex>. Значит, надо изменить <tex> t_2 </tex> и <tex> t_{2 | (2 + 1)} = t_3 </tex>. | Пусть теперь <tex> a_2 = a_2 \cdot d = \begin{pmatrix} 0 & 1 \\ 2 & 0 \end{pmatrix} \cdot \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} </tex>. Значит, надо изменить <tex> t_2 </tex> и <tex> t_{2 | (2 + 1)} = t_3 </tex>. | ||
| − | <tex> t_2' = t_2 \cdot s_{2, 2}^{-1} \cdot d \cdot s_{2, 2} = t_2 \cdot | + | <tex> t_2' = t_2 \cdot s_{2, 2}^{-1} \cdot d \cdot s_{2, 2} = t_2 \cdot (s_2^{-1} \cdot s_2)^{-1} \cdot d \cdot (t_2^{-1} \cdot t_2) = t_2 \cdot d = a_2' </tex> |
| − | <tex> t_3' = t_3 \cdot s_{2, 3}^{-1} \cdot d \cdot s_{2, 3} = t_3 \cdot ( | + | После этого дерево выглядит так: |
| + | |||
| + | <tex> \begin{array}{c||c||c||c||c} \begin{pmatrix} 1 & 0 \\ 0 & 2 \end{pmatrix} & | ||
| + | \begin{pmatrix} 1 & 2 \\ 0 & 2 \end{pmatrix} & | ||
| + | \begin{pmatrix} 3 & 4 \\ 2 & 4 \end{pmatrix} & | ||
| + | \begin{pmatrix} 1 & 10 \\ 0 & 8 \end{pmatrix} & | ||
| + | \begin{pmatrix} 1 & 0 \\ 2 & 1 \end{pmatrix} \\ | ||
| + | \hline | ||
| + | t_0 = a_0 & t_1 = a_0 \cdot a_1 & t_2 = a_2' & t_3 = a_0 \cdot a_1 \cdot a_2 \cdot a_3 & t_4 = a_4 \\ | ||
| + | \end{array} </tex> | ||
| + | |||
| + | <tex> t_3' = t_3 \cdot s_{2, 3}^{-1} \cdot d \cdot s_{2, 3} = t_3 \cdot (s_2'^{-1} \cdot s_3)^{-1} \cdot d \cdot s_2'^{-1} \cdot s_3 = t_3 \cdot s_3^{-1} \cdot s_2' \cdot d \cdot s_2'^{-1} \cdot s_3 = \\ = t_3 \cdot (a_0 \cdot a_1 \cdot a_2 \cdot a_3)^{-1} \cdot (a_0 \cdot a_1 \cdot a_2') \cdot d \cdot (a_0 \cdot a_1 \cdot a_2')^{-1} \cdot (a_0 \cdot a_1 \cdot a_2 \cdot a_3) = \\ = \begin{pmatrix} 1 & 10 \\ 0 & 8 \end{pmatrix} \cdot \begin{pmatrix} 1 & 10 \\ 0 & 8 \end{pmatrix}^{-1} \cdot \begin{pmatrix} 7 & 12 \\ 4 & 8 \end{pmatrix} \cdot \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} \begin{pmatrix} 7 & 12 \\ 4 & 8 \end{pmatrix}^{-1} \cdot \begin{pmatrix} 1 & 10 \\ 0 & 8 \end{pmatrix} </tex> | ||
=== Время работы === | === Время работы === | ||
Версия 00:12, 12 июня 2012
Обычное дерево Фенвика позволяет выполнять некоторую ассоциативную, коммутативную, обратимую операцию на отрезке с изменением элементов. Описываемая модификация дает возможность отказаться от коммутативности .
Содержание
Обновление элемента
Как и ранее, для обновления элемента в дереве нужно изменить все, что хранит результат операции с этим элементом. Но теперь нельзя просто применить операцию (далее будем использовать мультипликативную нотацию) ко всем нужным элементам дерева. Пусть мы хотим изменить на , в данный момент обновляем элемент дерева с индексом . Вместо мы получим (так как больше нельзя переставлять элементы местами в операции на отрезке, ответ будет неверен).
Решение — нужно удалить отрезок после изменяемого элемента, изменить элемент, после чего добавить этот отрезок снова. Пусть — результат выполнения операции на префиксе ; — результат ее выполнения на отрезке . Тогда элемент дерева с индексом обновляется как .
Доказательство
Может показаться, что этот способ не работает, так как , возможно, уже было изменено, а — еще нет, значит, мы удаляем не тот отрезок, который должны удалить. Убедимся, что на самом деле все обновляется правильно. Учитывая, что , получаем:
;
, то есть элемент дерева изменяется на правильное значение.
Пример
Пусть есть массив из пяти матриц :
Пусть — операция умножения матриц. Дерево Фенвика выглядит так:
Пусть теперь . Значит, надо изменить и .
После этого дерево выглядит так:
Время работы
Пусть в дереве элементов. Так как для каждого из изменяемых элементов дерева мы совершаем дополнительно запрос суммы на отрезке(а он работает за операций), то асимптотическое время работы обновления элемента ухудшается до .
Выполнение запроса
Выполнение запроса делается так же, как и в обычном дереве Фенвика, с той лишь разницей, что теперь важен порядок операндов в операции .