问题描述
小易在维护数据的时候遇到一个需求,具体来说小易有一系列数据,这些数据了构成一个长度为n的数字序列,接下来小易会在这个序列上进行q次操作。
每次操作有一个查询的数字x,小易需要将序列数据中所有大于等于x的数字都减一,并输出在本次操作中有多少个数字被减一了。
小易犯了难,希望你能帮帮他。
输入描述
第一行n,q,表示数字个数和操作个数。
接下来一行n个数表示初始的数字。
接下来q行,每行一个数,表示指定的数字x。
1 <= n, q <= 200000, 1 <= (a_{i}), x <= n
输出描述
对于每个询问,输出一个数字表示答案
输入例子1
4 3
1 2 3 4
4
3
1
输出例子1
1
2
4
输入例子2
3 2
1 2 3
3
3
输出例子2
1
0
解题思路
- 暴力解法
暴力解法很容易想到,直接按题目说的来做就可以了 - 优化
这个数据量,显然需要用O(nlogn)或者O(n)算法,则会想到排序。如果从大到小排,那么每次查询一个数字x,使得大于等于x的数字都会-1,那么数列还是有序的。也就是数列始终都是有序的,这样就可以进行剪枝了,遍历到小于x的直接break跳出循环即可。
代码
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int q = sc.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
Arrays.sort(arr);
for (int i = 0; i < q; i++) {
int num = sc.nextInt();
System.out.println(column(arr, num));
}
}
private static int column(int[] arr, int num) {
int count = 0;
for (int i = arr.length - 1; i >= 0; i--) {
if (arr[i] >= num) {
arr[i]--;
count++;
} else {
break;
}
}
return count;
}
}