Skip to content

Prefix Sum Array

Precompute cumulative sums to answer range sum queries in constant time.

A prefix sum array stores cumulative sums so that any range sum can be computed in constant time.

You use it when many range sum queries are performed on static data.

Problem

Given an array AA of length nn, support queries of the form:

i=lrA[i] \sum_{i=l}^{r} A[i]

where

0lr<n 0 \le l \le r < n

Structure

Define a prefix array PP such that:

P[i]=A[0]+A[1]++A[i] P[i] = A[0] + A[1] + \dots + A[i]

Algorithm

Build the prefix array:

build_prefix(A):
    n = length(A)
    P[0] = A[0]
    for i from 1 to n - 1:
        P[i] = P[i - 1] + A[i]
    return P

Answer a range query:

range_sum(P, l, r):
    if l == 0:
        return P[r]
    return P[r] - P[l - 1]

Example

Let

A=[8,3,5,1,9] A = [8, 3, 5, 1, 9]

Compute:

P=[8,11,16,17,26] P = [8, 11, 16, 17, 26]

Query sum from index 11 to 33:

i=13A[i]=3+5+1=9 \sum_{i=1}^{3} A[i] = 3 + 5 + 1 = 9

Using prefix sums:

P[3]P[0]=178=9 P[3] - P[0] = 17 - 8 = 9
stepvalue
P[3]17
P[0]8
result9

Correctness

Each prefix value P[i]P[i] stores the sum of elements from index 00 to ii. Subtracting P[l1]P[l-1] removes the contribution of elements before index ll, leaving exactly the sum over [l,r][l, r].

Complexity

operationtime
buildO(n)O(n)
queryO(1)O(1)

Space usage:

O(n) O(n)

When to Use

Prefix sums are appropriate when:

  • the array does not change
  • many range sum queries are required
  • preprocessing time is acceptable

They are less suitable when:

  • frequent updates occur
  • memory must remain minimal

In those cases, use Fenwick trees or segment trees.

Implementation

def build_prefix(a):
    p = [0] * len(a)
    p[0] = a[0]
    for i in range(1, len(a)):
        p[i] = p[i - 1] + a[i]
    return p

def range_sum(p, l, r):
    if l == 0:
        return p[r]
    return p[r] - p[l - 1]
func BuildPrefix(a []int) []int {
    n := len(a)
    p := make([]int, n)
    p[0] = a[0]
    for i := 1; i < n; i++ {
        p[i] = p[i-1] + a[i]
    }
    return p
}

func RangeSum(p []int, l, r int) int {
    if l == 0 {
        return p[r]
    }
    return p[r] - p[l-1]
}