# Range Sum Query 2D - Mutable in C++

Suppose we have a 2D matrix called matrix, we have to calculate the sum of the elements inside the rectangle defined by its upper left corner and lower right corner.

So, if the input is like

 3 0 1 4 2 5 6 3 2 1 1 2 0 1 5 4 1 0 1 7 1 0 3 0 5

So will be methods to find sum, update value, if we call them like

sumRegion(2, 1, 4, 3)

update(3, 2, 2)

sumRegion(2, 1, 4, 3) ,

then the output will be 8 and 10, as the above rectangle (with the green color) is defined by (2,1) and (4, 3), which contains sum = 8.

To solve this, we will follow these steps −

• Define one 2D array tree

• Define one 2D array value

• Define initializer that takes matrix as input

• n := row size of matrix

• m := (if not n is non-zero, then 0, otherwise col size of matrix)

• value := Define one 2D array of size n x m

• tree := Define one 2D array of order (n + 1) x (m + 1)

• for initialize i := 0, when i − n, update (increase i by 1), do −

• for initialize j := 0, when j < m, update (increase j by 1), do −

• update(i, j, matrix[i, j])

• Define a function update(), this will take row, col, val,

• if n is same as 0 or m is same as 0, then −

• return

• delta := val - value[row, col]

• value[row, col] := val

• for initialize i := row + 1, when i <= n, update i := i + i & (-i), do −

• for initialize j := col + 1, when j <= m, update j := j + j & (-j), do −

• tree[i, j] := tree[i, j] + delta

• Define a function sum(), this will take row, col,

• ret := 0

• for initialize i := row, when i > 0, update i := i - i & (-i), do −

• for initialize j := col, when j > 0, update j := j - j & (-j), do −

• ret := ret + tree[i, j]

• return ret

• Define a function sumRegion(), this will take row1, col1, row2, col2,

• if m is same as 0 or n is same as 0, then −

• return 0

• (increase row2 by 1)

• (increase row1 by 1)

• (increase col1 by 1)

• (increase col2 by 1)

• return sum(row2, col2) + sum(row1 - 1, col1 - 1) - sum(row1 - 1, col2) - sum(row2, col1 - 1)

## Example

Let us see the following implementation to get better understanding −

Live Demo

#include <bits/stdc++.h>
using namespace std;
class NumMatrix {
public:
int n, m;
vector<vector<int>> tree;
vector<vector<int>> value;
NumMatrix(vector<vector<int>> &matrix) {
n = matrix.size();
m = !n ? 0 : matrix[0].size();
value = vector<vector<int>>(n, vector<int>(m));
tree = vector<vector<int>>(n + 1, vector<int>(m + 1));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
update(i, j, matrix[i][j]);
}
}
}
void update(int row, int col, int val) {
if (n == 0 || m == 0)
return;
int delta = val - value[row][col];
value[row][col] = val;
for (int i = row + 1; i <= n; i += i & (-i)) {
for (int j = col + 1; j <= m; j += j & (-j)) {
tree[i][j] += delta;
}
}
}
int sum(int row, int col) {
int ret = 0;
for (int i = row; i > 0; i -= i & (-i)) {
for (int j = col; j > 0; j -= j & (-j)) {
ret += tree[i][j];
}
}
return ret;
}
int sumRegion(int row1, int col1, int row2, int col2) {
if (m == 0 || n == 0)
return 0;
row2++;
row1++;
col1++;
col2++;
return sum(row2, col2) + sum(row1 - 1, col1 - 1) - sum(row1 - 1, col2) - sum(row2, col1 - 1);
}
};
main() {
vector<vector<int>> v = {
{3, 0, 1, 4, 2},
{5, 6, 3, 2, 1},
{1, 2, 0, 1, 5},
{4, 1, 0, 1, 7},
{1, 0, 3, 0, 5}};
NumMatrix ob(v);
cout << (ob.sumRegion(2, 1, 4, 3)) << endl;
ob.update(3, 2, 2);
cout << (ob.sumRegion(2, 1, 4, 3)) << endl;
}

## Input

vector<vector<int>> v = {
{3, 0, 1, 4, 2},
{5, 6, 3, 2, 1},
{1, 2, 0, 1, 5},
{4, 1, 0, 1, 7},
{1, 0, 3, 0, 5}};
NumMatrix ob(v);
cout << (ob.sumRegion(2, 1, 4, 3)) << endl;
ob.update(3, 2, 2);
cout << (ob.sumRegion(2, 1, 4, 3)) << endl;

## Output

8
10

Updated on: 21-Jul-2020

263 Views