Alex's Anthology of Algorithms Common Code for Contests in Concise C++
Data Structures / Fenwick Trees

2.6.2 Fenwick Tree (Range Update, Point Query)

2-Data-Structures/2.6.2_Fenwick_Tree_(Range_Update,_Point_Query).cpp

View on GitHub

Maintain a numerical array while supporting range increments and point queries. This is done by storing the difference array in a Fenwick tree: adding x to [lo, hi] adds +x at lo and -x after hi, and the value at index i is the prefix sum of those differences through i.

  • FenwickRUPQ<T>(n) constructs an array with 0-based indices [0, n), with values set to 0.
  • size() returns the size of the array.
  • at(i) returns the value at index i.
  • add(i, x) adds x to the value at index i.
  • add(lo, hi, x) adds x to the values at all indices from lo to hi, inclusive.

Implementation

#include <vector>

template<class T>
class FenwickRUPQ {
  int len;
  std::vector<T> tree;

 public:
  explicit FenwickRUPQ(int n) : len(n), tree(n + 2) {}

  int size() const { return len; }

  T at(int i) const {
    T res = 0;
    for (i++; i > 0; i -= i & -i) {
      res += tree[i];
    }
    return res;
  }

  void add(int i, const T &x) {
    for (i++; i <= len + 1; i += i & -i) {
      tree[i] += x;
    }
  }

  void add(int lo, int hi, const T &x) {
    add(lo, x);
    add(hi + 1, -x);
  }
};

Example Usage

#include <iostream>
using namespace std;

int main() {
  FenwickRUPQ<int> t(5);
  t.add(0, 1, 5);
  t.add(1, 2, 5);
  t.add(2, 4, 10);
  cout << "Values: ";
  for (int i = 0; i < t.size(); i++) {
    cout << t.at(i) << " ";
  }
  cout << endl;
  return 0;
}

Example Output

Values: 5 10 15 10 10