A 2D prefix sum is a technique used to calculate the sum of elements in any submatrix efficiently. It precomputes the sum of elements from the top-left corner to every cell, allowing each submatrix sum query to be answered in O(1) time.
- It extends the concept of prefix sums from 1D arrays to 2D matrices.
- It uses the inclusion-exclusion principle to avoid repeated calculations.
Example
Input:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
Prefix sum matrix is:
1 3 6 10
6 14 24 36
15 33 54 78
28 60 96 136
Each element of the prefix sum matrix represents the sum of all elements in the rectangle from the top-left corner (0, 0) to that position.
- prefix[0][0] = 1
- prefix[0][1] = 1 + 2 = 3
- prefix[0][2] = 1 + 2 + 3 = 6
- prefix[0][3] = 1 + 2 + 3 + 4 = 10
- prefix[1][0] = 1 + 5 = 6
- prefix[1][1] = 1 + 2 + 5 + 6 = 14
- prefix[1][2] = 1 + 2 + 3 + 5 + 6 + 7 = 24
- prefix[1][3] = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 = 36
- prefix[2][0] = 1 + 5 + 9 = 15
- prefix[2][1] = 1 + 2 + 5 + 6 + 9 + 10 = 33
- prefix[2][2] = 1 + 2 + 3 + 5 + 6 + 7 + 9 + 10 + 11 = 54
- prefix[2][3] = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 = 78
- prefix[3][0] = 1 + 5 + 9 + 13 = 28
- prefix[3][1] = 1 + 2 + 5 + 6 + 9 + 10 + 13 + 14 = 60
- prefix[3][2] = 1 + 2 + 3 + 5 + 6 + 7 + 9 + 10 + 11 + 13 + 14 + 15 = 96
- prefix[3][3] = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 = 136

Approaches to Calculate Prefix Sum of a Matrix
The prefix sum matrix can be constructed using the following approach.
1. Constructing the Prefix Sum Matrix
For every cell (i, j), add the current element, the prefix sum from the top, and the prefix sum from the left. The overlapping top-left region is subtracted once.
The prefix sum for any cell can be calculated using:
prefix[i][j] = arr[i][j]
+ prefix[i-1][j]
+ prefix[i][j-1]
- prefix[i-1][j-1]
The top and left prefix sums are added, while the top-left prefix sum is subtracted because it is counted twice.
For example, for prefix[1][1]:
prefix[1][1]
= arr[1][1] + prefix[0][1] + prefix[1][0] - prefix[0][0]
= 5 + 3 + 5 - 1
= 12
This preprocessing allows us to calculate the sum of any rectangular region of the matrix without traversing all its elements.
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> prefixSum2D(
const vector<vector<int>>& arr)
{
int n = arr.size();
int m = arr[0].size();
vector<vector<int>> prefix(n, vector<int>(m, 0));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
prefix[i][j] = arr[i][j];
if (i > 0)
prefix[i][j] += prefix[i - 1][j];
if (j > 0)
prefix[i][j] += prefix[i][j - 1];
if (i > 0 && j > 0)
prefix[i][j] -= prefix[i - 1][j - 1];
}
}
return prefix;
}
int main()
{
vector<vector<int>> arr = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}
};
vector<vector<int>> prefix = prefixSum2D(arr);
for (const auto& row : prefix) {
for (int value : row)
cout << value << " ";
cout << '\n';
}
return 0;
}
import java.util.ArrayList;
class GfG {
public static ArrayList<ArrayList<Integer>> prefixSum2D(int[][] arr) {
// number of rows
int n = arr.length;
// number of columns
int m = arr[0].length;
// Initialize prefix with 0s
ArrayList<ArrayList<Integer>> prefix = new ArrayList<>();
for (int i = 0; i < n; i++) {
prefix.add(new ArrayList<>());
for (int j = 0; j < m; j++) {
prefix.get(i).add(0);
}
}
// Compute prefix sum matrix
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
// Start with original value
int value = arr[i][j];
// Add value from top cell if it exists
if (i > 0) {
value += prefix.get(i - 1).get(j);
}
// Add value from left cell if it exists
if (j > 0) {
value += prefix.get(i).get(j - 1);
}
// Subtract overlap from top-left diagonal if it exists
if (i > 0 && j > 0) {
value -= prefix.get(i - 1).get(j - 1);
}
prefix.get(i).set(j, value);
}
}
return prefix;
}
public static void main(String[] args) {
int[][] arr = {
{1,