This repository has been archived on 2022-06-22. You can view files and clone it, but cannot push or open issues or pull requests.
usaco-guide/content/4_Silver/6_Silver_Psum.md
2020-06-09 14:42:59 -04:00

3.7 KiB

slug title author order
/silver/prefix-sums Prefix Sums Eric Wei 6

Given an array A_1,A_2,\ldots,A_N, answer Q queries of the following form: compute A_L+A_{L+1}+\cdots+A_R.

Standard

Tutorials

This technique is also known as cumulative sum or partial sums.

  • Intro to USACO 11
  • CPH 9.1

USACO Silver Problems

These problems are relatively straightforward.

Now we'll look at some extensions.

Max Subarray Sum

(Note: This problem has a solution known as Kadane's Algorithm. Please don't use that solution; try to solve it with prefix sums.)

Extension:

2D Prefix Sums

Given a 2-dimensional array of size NxM, answer Q queries of the following form: Find the sum of all elements within the rectangle of indices (x1,y1) to (x2,y2).

Difference Array

Task: Given an array of size N, do the following operation Q times: add X to the values between i and j. Afterwards, print the final array.

Solution: Consider the array formed by a_i-a_{i-1}. When processing a range addition, only two values in this difference array change! At the end, we can recover the original array using prefix sums. (The math is left as an exercise to the reader.)

Prefix Minimum, XOR, etc.

Similar to prefix sums, you can also take prefix minimum or maximum; but you cannot answer min queries over an arbitrary range with prefix minimum. (This is because minimum doesn't have an inverse operation, the way subtraction is to addition.) On the other hand, XOR is its own inverse operation, meaning that the XOR of any number with itself is zero.

More Complex Applications

Instead of storing just the values themselves, you can also take a prefix sum over i\cdot a_i, or 10^i \cdot a_i, for instance. Some math is usually helpful for these problems; don't be afraid to get dirty with algebra!

For instance, let's see how to quickly answer the following type of query: Find

1\cdot a_l+2\cdot a_{l+1}+3\cdot a_{l+2}+\cdots+(r-l+1)\cdot a_{r}.

First, define the following:

ps[i] = a_1+a_2+a_3+a_4+\cdots+a_i
ips[i] = 1\cdot a_1+2\cdot a_2+\cdots+i\cdot a_i

Then, we have:

l\cdot a_l + (l+1) \cdot a_{l+1} + \cdots + r \cdot a_r = ips[r]-ips[l-1]
(l-1) \cdot a_l + (l-1) \cdot a_{l+1} + \cdot + (l-1) \cdot a_r = (l-1)(ps[r]-ps[l-1])

And so,

1\cdot a_l + 2 \cdot a_{l+1} + \cdots + (r-l+1) \cdot a_r = ips[r]-ips[l-1]-(l-1)(ps[r]-ps[l-1])

Which is what we were looking for!