Precompute cumulative information to answer range queries efficiently
Prefix arrays store cumulative information from the start of the array, while suffix arrays store information from the end. This preprocessing enables O(1) range queries for sums, products, XOR, or other associative operations.
Use when you need to answer multiple range queries efficiently, calculate subarray sums, find equilibrium points, or solve problems involving cumulative operations. Particularly useful when queries are more frequent than updates.
Store cumulative sums to answer range sum queries in O(1)
def prefix_sum(arr):
n = len(arr)
prefix = [0] * (n + 1)
# Build prefix sum array
for i in range(n):
prefix[i + 1] = prefix[i] + arr[i]
return prefix
def range_sum(prefix, left, right):
# Sum of arr[left:right+1]
return prefix[right + 1] - prefix[left]
# Example: Subarray sum equals k
def subarray_sum_k(arr, k):
count = 0
prefix_sum = 0
sum_freq = {0: 1} # Handle subarrays starting at index 0
for num in arr:
prefix_sum += num
# Check if (prefix_sum - k) exists
if prefix_sum - k in sum_freq:
count += sum_freq[prefix_sum - k]
sum_freq[prefix_sum] = sum_freq.get(prefix_sum, 0) + 1
return count
Use XOR properties to solve range XOR queries and bit manipulation problems
def prefix_xor(arr):
n = len(arr)
prefix = [0] * (n + 1)
for i in range(n):
prefix[i + 1] = prefix[i] ^ arr[i]
return prefix
def range_xor(prefix, left, right):
# XOR of arr[left:right+1]
return prefix[right + 1] ^ prefix[left]
# Example: Subarray XOR equals k
def subarray_xor_k(arr, k):
count = 0
xor_sum = 0
xor_freq = {0: 1}
for num in arr:
xor_sum ^= num
# Check if (xor_sum ^ k) exists
target = xor_sum ^ k
if target in xor_freq:
count += xor_freq[target]
xor_freq[xor_sum] = xor_freq.get(xor_sum, 0) + 1
return count
Efficiently handle multiple range updates with O(1) per update
def difference_array(n):
return [0] * (n + 1)
def range_update(diff, left, right, val):
# Add val to range [left, right]
diff[left] += val
diff[right + 1] -= val
def build_final_array(diff):
n = len(diff) - 1
result = [0] * n
current = 0
for i in range(n):
current += diff[i]
result[i] = current
return result
# Example: Corporate Flight Bookings
def corp_flight_bookings(bookings, n):
diff = [0] * (n + 1)
for first, last, seats in bookings:
diff[first - 1] += seats
diff[last] -= seats
result = []
current = 0
for i in range(n):
current += diff[i]
result.append(current)
return result
# Prefix Sum Template
def prefix_sum(arr):
n = len(arr)
prefix = [0] * (n + 1)
for i in range(n):
prefix[i + 1] = prefix[i] + arr[i]
return prefix
def range_sum(prefix, left, right):
return prefix[right + 1] - prefix[left]
# Difference Array Template
def range_update(diff, left, right, val):
diff[left] += val
diff[right + 1] -= val
def build_array(diff):
result = []
current = 0
for val in diff[:-1]:
current += val
result.append(current)
return result
Building prefix array takes O(n), each query is O(1). Range updates are O(1) with difference array.
Requires O(n) space to store the prefix/suffix/difference array.