DSA sheet / Range queries

Static Range Sum Queries

easy about 15 min Prefix sumsprefix-sumsqueriesoverflow
Open on CSES

Do these first: Maximum Subarray Sum

The problem in brief

You get an array of n integers (up to 200 000) and q queries (up to 200 000). Each query gives two positions a and b (1-indexed, inclusive); print the sum of the array values from a to b. The array never changes between queries.

Try it

Tab indents; press Esc, then Tab, to leave the box. Ctrl+Enter runs.

Hints

Stuck? Reveal one hint at a time. Each nudges without giving away the next.

The walkthrough

Spoilers ahead: open a section only after you have given the hints a fair try.

How to think

When many queries hit the same unchanging data, spend the effort once up front. The two costs are preprocessing and per-query time; brute force is O(1) preprocessing and O(n) per query, for a total of 4 * 10^10 at the limits. Prefix sums give O(n) preprocessing and O(1) per query.

The idea: let P[i] be the sum of the first i elements, with P[0] = 0. Then sum(a..b) = P[b] - P[a - 1]. The leading zero is the trick that removes the special case for ranges starting at position 1. This shape (build a summary once, answer each query by combining two lookups) is the seed of a whole family: 2D prefix sums, difference arrays, and even the Fenwick tree in the next problem, which handles updates too.

Intuition

A running odometer: reading it at position b and at position a - 1 and subtracting tells you the distance travelled between them, without re-driving the route.

Approach
  1. Read the array and build P with P[0] = 0, P[i] = P[i - 1] + x_i.
  2. For each query (a, b) print P[b] - P[a - 1].

Pitfalls: prefix sums reach 2 * 10^14 so use 64-bit; keep positions 1-indexed and P sized n + 1; print all answers with one buffered write, since there can be 200 000 lines.

Complexity

O(n + q) time, O(n) memory.

Solutions

Written from scratch and checked by compiling and running each one against a brute force on random inputs. Fast input/output, the way you would submit it.

Show solutions (C++17, Python 3, Java 17, Node.js)
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, q;
    cin >> n >> q;
    vector<long long> prefix(n + 1, 0);
    for (int i = 1; i <= n; i++) {
        long long x;
        cin >> x;
        prefix[i] = prefix[i - 1] + x;
    }
    string out;
    while (q--) {
        int a, b;
        cin >> a >> b;
        out += to_string(prefix[b] - prefix[a - 1]);
        out += '\n';
    }
    cout << out;
    return 0;
}

Problem: CSES Problem Set (Antti Laaksonen, University of Helsinki), CC BY-NC-SA 4.0. The explanations and code above are original (© Anupam Kumar).

Related problems

Back to the sheet