Fenwick Tree
Jul 10, 24point update, range query
#include <bits/stdc++.h>
using namespace std;
// Method to calculate prefix sum till index idx
int sum(int idx, vector<int>& F)
{
int runningSum = 0;
// Summing up all the partial sums
while (idx > 0) {
runningSum += F[idx];
int rightMostSetBit = (idx & (-idx));
idx -= rightMostSetBit;
}
return runningSum;
}
// Method to update the array by adding X to index idx
void add(int idx, int X, vector<int>& F)
{
while (idx < F.size()) {
F[idx] += X;
int rightMostSetBit = (idx & (-idx));
idx += rightMostSetBit;
}
}
// Method to calculate range sum from index l to r
int rangeQuery(int l, int r, vector<int>& F)
{
return sum(r, F) - sum(l - 1, F);
}
int main()
{
int n = 5;
// 1 - based indexing
vector<int> arr{ -1e9, 1, 2, 3, 4, 5 };
// Initially all the values of Fenwick tree are 0
vector<int> F(n + 1, 0);
// Build the fenwick tree
for (int i = 1; i <= n; i++) {
add(i, arr[i], F);
}
// query the sum from index 1 to 3
cout << rangeQuery(1, 3, F) << "\n";
// query the sum from index 2 to 5
cout << rangeQuery(2, 5, F) << "\n";
// Update element at index i to X
int i = 3;
int X = 7;
// We have passed X - arr[i] to the add method, because
// add method simply adds a number at a particular index
// so if we need to update the element, we need to pass
// the difference between the ith element and X to add
// method
add(i, X - arr[i], F);
// query the sum from index 1 to 3
cout << rangeQuery(1, 3, F) << "\n";
// query the sum from 2 to 5
cout << rangeQuery(2, 5, F) << "\n";
return 0;
}
query in 2d array
struct FenwickTree2D {
vector<vector<int>> bit;
int n, m;
// init(...) { ... }
int sum(int x, int y) {
int ret = 0;
for (int i = x; i >= 0; i = (i & (i + 1)) - 1)
for (int j = y; j >= 0; j = (j & (j + 1)) - 1)
ret += bit[i][j];
return ret;
}
void add(int x, int y, int delta) {
for (int i = x; i < n; i = i | (i + 1))
for (int j = y; j < m; j = j | (j + 1))
bit[i][j] += delta;
}
};
range update, point query
#include<bits/stdc++.h>
using namespace std;
vector<int> BITree;
void updateBIT(vector<int>& BITree, int n, int index, int val)
{
index = index + 1;
while (index <= n)
{
BITree[index] += val;
index += index & (-index);
}
}
int query(vector<int>& BITree, int index)
{
int sum = 0;
index = index + 1;
while (index > 0)
{
sum += BITree[index];
index -= index & (-index);
}
return sum;
}
void update(vector<int>& BITree, int l, int r, int n, int val)
{
updateBIT(BITree, n, l, val);
updateBIT(BITree, n, r + 1, -val);
}
int main() {
int n = 10;
vector<int> a = { 1,3,2,5,6,3,3,3,3,3 };
vector<int> tree(n + 1);
for (int i = 0; i < n; i++) {
if (i == 0) updateBIT(tree, n, i, a[i]);
else updateBIT(tree, n, i, a[i] - a[i - 1]);
}
for (int i = 0; i < n; i++) {
cout << query(tree, i) << " ";
}
cout << "\n";
// 1 3 2 5 6 3 3 3 3 3
update(tree, 4, 7, n, 3);
for (int i = 0; i < n; i++) {
cout << query(tree, i) << " ";
}
cout << "\n";
// 1 3 2 5 9 6 6 6 3 3
}
range update, range query
#include <bits/stdc++.h>
using namespace std;
int getSum(int BITree[], int index){
int sum = 0;
index = index + 1;
while (index > 0) {
sum += BITree[index];
index -= index & (-index);
}
return sum;
}
void updateBIT(int BITree[], int n, int index, int val){
index = index + 1;
while (index <= n) {
BITree[index] += val;
index += index & (-index);
}
}
int sum(int x, int BITTree1[], int BITTree2[]){
return (getSum(BITTree1, x) * x) - getSum(BITTree2, x);
}
void updateRange(int BITTree1[], int BITTree2[], int n, int val, int l, int r){
updateBIT(BITTree1, n, l, val);
updateBIT(BITTree1, n, r + 1, -val);
updateBIT(BITTree2, n, l, val * (l - 1));
updateBIT(BITTree2, n, r + 1, -val * r);
}
int rangeSum(int l, int r, int BITTree1[], int BITTree2[]){
return sum(r, BITTree1, BITTree2) - sum(l - 1, BITTree1, BITTree2);
}
int* constructBITree(int n)
{
int* BITree = new int[n + 1];
for (int i = 1; i <= n; i++)
BITree[i] = 0;
return BITree;
}
int main()
{
int n = 5;
int *BITTree1, *BITTree2;
BITTree1 = constructBITree(n);
BITTree2 = constructBITree(n);
int l = 0, r = 4, val = 5;
updateRange(BITTree1, BITTree2, n, val, l, r);
// [5,5,5,5,5]
l = 2, r = 4, val = 10;
updateRange(BITTree1, BITTree2, n, val, l, r);
// [5,5,15,15,15]
l = 1, r = 4;
cout << "Sum of elements from [" << l << "," << r << "] is ";
cout << rangeSum(l, r, BITTree1, BITTree2) << "\n";
//Sum of elements from [1,4] is 50
return 0;
}
reference: