guest@cp-base:~/home/range-queries$
templates/prefix-sum-2d.cpp
compilable
$cat templates/prefix-sum-2d

Prefix Sum 2D

2D prefix sum for O(1) rectangle sum queries on a static grid.

#prefix-sum#2d#range-query#static-grid#inclusion-exclusion
Log in to track progress, save custom versions, and organize into collections.Log In
$cat source_code/
cpp
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int MAXN = 1005;
ll psum[MAXN][MAXN];
int N, M;

void build(ll a[][MAXN]) {
    for (int i = 1; i <= N; i++)
        for (int j = 1; j <= M; j++)
            psum[i][j] = a[i][j] + psum[i-1][j] + psum[i][j-1] - psum[i-1][j-1];
}

ll query(int x1, int y1, int x2, int y2) {
    if (x1 > x2) swap(x1, x2);
    if (y1 > y2) swap(y1, y2);
    return psum[x2][y2] - psum[x1-1][y2] - psum[x2][y1-1] + psum[x1-1][y1-1];
}
19 linesutf-8
$cat explanation_notes.md
notes_viewer --renderedmarkdown (math enabled)

2D Prefix Sum

Preprocess a static n×mn \times m grid once, then answer any rectangle sum query in O(1)O(1).

Building

Construct prefix matrix PP where P[i][j]P[i][j] is the sum of all elements in the sub-grid from (1,1)(1,1) to (i,j)(i,j):

P[i][j]=A[i][j]+P[i1][j]+P[i][j1]P[i1][j1]P[i][j] = A[i][j] + P[i-1][j] + P[i][j-1] - P[i-1][j-1]

Query

Sum over rectangle from (x1,y1)(x_1, y_1) to (x2,y2)(x_2, y_2) using inclusion-exclusion:

sum=P[x2][y2]P[x11][y2]P[x2][y11]+P[x11][y11]\text{sum} = P[x_2][y_2] - P[x_1-1][y_2] - P[x_2][y_1-1] + P[x_1-1][y_1-1]

When to Use

  • Sum queries over rectangular sub-grids in a static 2D array

  • Grid path counting, density queries, 2D sliding window sums

  • Any problem where you build once and query many times
  • Complexity

  • Build — O(nm)O(n \cdot m)

  • Query — O(1)O(1)

  • Space — O(nm)O(n \cdot m)