Range Sum Queries (Prefix Sums)

easy Arrays

Problem

The first line has the array values. Each next line has two indexes l and r (0-based, l <= r). For each query print the sum of the values from index l to index r (both included). Answer every query in O(1) after one pass over the array.

Constraints

  • 1 <= n, q <= 10^5

Examples

Input

1 2 3 4 5
0 4
1 3

Output

15
9

Solutions

Best approachTime O(n + q)Space O(n)

Adding the values for every query costs O(n) each. One prefix array costs O(n) once, and then every query is a single subtraction. Use long for the sums: three values of 10^9 already pass the int limit.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Answer range sums.
 * Input   : Values line, then query lines.
 * Output  : One sum per query.
 * Approach: Prefix sums.
 * Time    : O(n + q)
 * Space   : O(n)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    // This method solves the task. It receives the input and returns the answer.
    static String[] solve(String[] lines) {
        // Step 1: The first line holds the values. prefix[i] = the sum of the first i values. prefix[0] = 0.
        String[] parts = lines[0].split(" ");
        long[] prefix = new long[parts.length + 1];
        for (int i = 0; i < parts.length; i++) {
            prefix[i + 1] = prefix[i] + Long.parseLong(parts[i]);
        }

        // Step 2: The sum of the values from l to r is prefix[r + 1] - prefix[l].
        String[] output = new String[lines.length - 1];
        for (int i = 1; i < lines.length; i++) {
            String[] query = lines[i].split(" ");
            int left = Integer.parseInt(query[0]);
            int right = Integer.parseInt(query[1]);
            output[i - 1] = String.valueOf(prefix[right + 1] - prefix[left]);
        }
        return output;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        java.util.List<String> all = new java.util.ArrayList<>();
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine().trim();
            if (!line.isEmpty()) {
                all.add(line);
            }
        }
        String[] lines = all.toArray(new String[0]);
        System.out.println(String.join("\n", solve(lines)));
    }
}
Hints (1)
  1. Why is prefix one element longer than the array?