Изумительная структура данных. Классический пример гениальной мысли.
Дерево Фенвика позволяет за O(log(N)) определять значение обратимой функции на интервале массива [L,R].
Обратимая функция:
1) Сумма на интервале [L,R]
2) Минимум на интервале
3) Максимум на интервале
Теория:
1) Статья Алексея Лахно
2) Статья Максима Иванова.
Осознать сам подход поможет это изображение:
Запомним два правила.
1) При добавлении нового элемента делаем подъем вверх
2) При подсчете суммы элементов в интервале [0,X] делаем спуск вниз
Реализация:
- vector<int> b(MAX_VALUE+1);
-
- void add(int x, int delta) {
- for (; x <= MAX_VALUE; x = x | (x + 1))
- b[x] += delta;
- }
-
- int sum(int x) {
- int res = 0;
- for (; x >= 0; x = (x & (x + 1)) - 1)
- res += b[x];
- return res;
- }
* This source code was highlighted with Source Code Highlighter.
Практика:
Задача: 1028 (acm.timus.ru)
Решение: здесь
P.S: Не забываем, что дерево Фенвика легко интерпретируется на многомерный случай
Комментариев нет:
Отправить комментарий