802.離散化
阿新 • • 發佈:2020-10-09
假定有一個無限長的數軸,數軸上每個座標上的數都是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
參考程式碼
import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Scanner; class Pair { public int first; public int second; public Pair(int first, int second) { this.first = first; this.second = second; } } public class Main { public static int find(List<Integer> list, int x) { int l = 0, r = list.size() - 1; while (l < r) { int mid = l + r >> 1; if (list.get(mid) >= x) { r = mid; } else { l = mid + 1; } } return l + 1; } public static int unique(List<Integer> list) { int j = 0; for (int i = 1; i < list.size(); i++) { if (list.get(i) != list.get(j)) { list.set(++j, list.get(i)); } } return j + 1; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int m = sc.nextInt(); int[] a = new int[n + 2 * m + 1]; int[] s = new int[n + 2 * m + 1]; List<Pair> list = new ArrayList<>(); List<Pair> query = new ArrayList<>(); List<Integer> key = new ArrayList<>(); for (int i = 0; i < n; i++) { int x = sc.nextInt(); int c = sc.nextInt(); list.add(new Pair(x, c)); key.add(x); } for (int i = 0; i < m; i++) { int l = sc.nextInt(); int r = sc.nextInt(); query.add(new Pair(l, r)); key.add(l); key.add(r); } Collections.sort(key); key = key.subList(0, unique(key)); for (Pair item : list) { int index = find(key, item.first); a[index] += item.second; } for (int i = 1; i <= key.size(); i++) { s[i] = s[i - 1] + a[i]; } for (Pair item : query) { int l = find(key, item.first); int r = find(key, item.second); System.out.println(s[r] - s[l - 1]); } sc.close(); } }