802. 区间和

64 阅读1分钟

802. 区间和 - AcWing题库

Question

Content

假定有一个无限长的数轴,数轴上每个坐标上的数都是 0。

现在,我们首先进行 n 次操作,每次操作将某一位置 x 上的数加 c。

接下来,进行 m 次询问,每个询问包含两个整数 l 和 r,你需要求出在区间 [l,r] 之间的所有数的和。

输入格式

第一行包含两个整数 n 和 m。

接下来 n 行,每行包含两个整数 x 和 c。

再接下来 m 行,每行包含两个整数 l 和 r。

输出格式

共 m 行,每行输出一个询问中所求的区间内数字和。

数据范围

−109 ≤ x ≤ 109,

1 ≤ n,m ≤ 105,

−109 ≤ l ≤ r ≤ 109,

−10000 ≤ c ≤ 10000

输入样例:

3 3
1 2
3 6
7 5
1 3
4 6
7 8

输出样例:

8
0
5

Solution

Java

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;

public class Main {

    private static final int N = 3 * (int) 1e5;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();

        List<Integer> arr = new ArrayList<>();
        List<int[]> add = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            int x = scanner.nextInt();
            int c = scanner.nextInt();
            add.add(new int[]{x, c});
            arr.add(x);
        }

        List<int[]> query = new ArrayList<>();
        for (int i = 0; i < m; i++) {
            int l = scanner.nextInt();
            int r = scanner.nextInt();
            query.add(new int[]{l, r});
            arr.add(l);
            arr.add(r);
        }

        List<Integer> distinctSortedArr = arr.stream().distinct()
                .sorted().collect(Collectors.toList());

        int[] a = new int[N];
        for (int[] e : add) {
            int idx = Collections.binarySearch(distinctSortedArr, e[0]) + 1;
            a[idx] += e[1];
        }

        int[] s = new int[N];
        for (int i = 1; i <= distinctSortedArr.size(); i++) {
            s[i] = s[i - 1] + a[i];
        }

        for (int[] e : query) {
            int l = Collections.binarySearch(distinctSortedArr, e[0]) + 1;
            int r = Collections.binarySearch(distinctSortedArr, e[1]) + 1;
            System.out.println(s[r] - s[l - 1]);
        }
    }

}