Fenwick Tree2 D Algorithm
The Fenwick Tree 2D Algorithm, also referred to as the Binary Indexed Tree (BIT) 2D Algorithm, is an advanced data structure that efficiently performs update and query operations on two-dimensional arrays. It is particularly useful in addressing problems that involve cumulative frequency tables and prefix sums, where one needs to calculate the sum of elements within a given submatrix. The Fenwick Tree 2D Algorithm is an extension of the one-dimensional Fenwick Tree, which is designed for similar operations on one-dimensional arrays. It leverages the binary representation of indices to perform updates and queries in logarithmic time complexity, making it a preferred choice for handling large datasets.
In a two-dimensional Fenwick Tree, each node stores the cumulative sum of a submatrix, and the tree structure follows a parent-child relationship based on the least significant bit (LSB) of the indices. To update an element in the 2D array, the algorithm traverses the tree structure, updating the affected nodes along the way. Similarly, to query the sum of a submatrix, the algorithm performs multiple queries on the tree, combining the results to obtain the final sum. The key advantage of the Fenwick Tree 2D Algorithm is its ability to perform both update and query operations in O(log(m) * log(n)) time complexity, where m and n are the dimensions of the array. This efficiency makes the algorithm a popular choice in competitive programming and various applications dealing with two-dimensional data manipulation.
/*************************************************************************************
Fenwick tree for sum on the rectangle and update of an element.
O(logN ^ 2) on query.
Based on problem 3013 from informatics.mccme.ru:
http://informatics.mccme.ru/moodle/mod/statements/view.php?chapterid=3013#1
*************************************************************************************/
#include <iostream>
#include <fstream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <cassert>
#include <utility>
#include <iomanip>
using namespace std;
const int MAXN = 1050;
int n, m;
int qn;
char q[10];
int f[MAXN][MAXN];
void update(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))
f[i][j] += delta;
}
int getSum(int x, int y) {
int res = 0;
for (int i = x; i > 0; i = (i & (i + 1)) - 1)
for (int j = y; j > 0; j = (j & (j + 1)) - 1)
res += f[i][j];
return res;
}
int getSum(int xFrom, int xTo, int yFrom, int yTo) {
return getSum(xTo, yTo) - getSum(xTo, yFrom - 1) - getSum(xFrom - 1, yTo) + getSum(xFrom - 1, yFrom - 1);
}
int main() {
//assert(freopen("input.txt","r",stdin));
//assert(freopen("output.txt","w",stdout));
scanf("%d %d\n", &n, &qn);
m = n;
for (int i = 1; i <= qn; i++) {
scanf("%s", &q);
if (q[0] == 'A') {
int x, y;
scanf("%d %d\n", &x, &y);
update(x, y, 1);
}
else {
int xFrom, xTo, yFrom, yTo;
scanf("%d %d %d %d\n", &xFrom, &yFrom, &xTo, &yTo);
if (xFrom > xTo)
swap(xFrom, xTo);
if (yFrom > yTo)
swap(yFrom, yTo);
printf("%d\n", getSum(xFrom, xTo, yFrom, yTo));
}
}
return 0;
}