PassFront
  1. PassFront
  2. База знаний
  3. Деревья и кучи

Что такое дерево отрезков и дерево Фенвика и когда они нужны?

Деревья и кучи

Обе структуры решают задачу «запросы на отрезке плюс изменения элементов» за O(log n) на операцию, тогда как массив префиксных сумм отвечает за O(1), но обновляется за O(n).

Дерево отрезков

  • Каждый узел хранит агрегат своего отрезка, корень — всего массива, листья — отдельных элементов; память около 4n в массивной реализации.
  • Подходит любая ассоциативная операция: сумма, минимум, максимум, НОД.
  • Ленивое проталкивание (lazy propagation) даёт и массовые обновления вида «прибавить x на [l, r]» за O(log n).

Дерево Фенвика (BIT)

  • Массив длины n+1, где ячейка i отвечает за отрезок длины i & -i, заканчивающийся в i.
  • Префиксная сумма и точечное обновление — O(log n), код в десяток строк, памяти ровно n.
class Fenwick {
  #t;
  constructor(n) { this.#t = new Array(n + 1).fill(0); }
  add(i, delta) { // i с 1
    for (; i < this.#t.length; i += i & -i) this.#t[i] += delta;
  }
  prefix(i) { // сумма a[1..i]
    let s = 0;
    for (; i > 0; i -= i & -i) s += this.#t[i];
    return s;
  }
}
// сумма на [l, r] = prefix(r) - prefix(l - 1)

Как выбрать

  • Сумма или XOR с точечными изменениями — Фенвик: проще и быстрее по константе.
  • Минимум на отрезке или массовые обновления — дерево отрезков: у минимума нет обратной операции, и разность префиксов не работает.

Коротко для собеседования

Префиксные суммы хороши, пока массив не меняется; если нужны и запросы на отрезке, и обновления, берут Фенвика или дерево отрезков за O(log n). Фенвик короче и быстрее для сумм, а для минимума и массовых обновлений нужно дерево отрезков, потому что у минимума нет обратной операции.

Другие вопросы раздела