解题要素,对于任意一个题目来讲,我们做题之前,肯定是要先去都题目,在读题的过程当中,挖掘题目所具备的性质,想整个寻找答案的过程,我们是不是可以用之前学过的算法模拟出来?(流程是类似的?)是不是在求解的某一步当中,我们需要什么值,这个值可以用我们学过的什么算法先预处理出来?方便我们进行下一步的思考?
对于给定的数组,我们排序后是能够处理出来s[i]数组的(我们存储的前缀和是c[i]数组,是数量公式得到的值)。通过前缀和我们能够知道第K小的数的值,整个过程我们要去二分前缀和s数组的下标,得到他得值就是我们要求的res
错误原因:k没开long
由于数据范围N,可以推出来k是需要long数据类型的
CODE
package 基础算法_二分;
import java.util.Arrays;
import java.util.Scanner;
public class 基德的神秘冒险{
static int N = 3_00_010;
static long [] a = new long [N];
static long [] c = new long [N];
static long [] s = new long [N];
static int n, q;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
q = sc.nextInt();
for(int i = 1; i <= n; i ++){
a[i] = sc.nextLong();
}
//排序
Arrays.sort(a, 1, n + 1);
for(int i = 1; i <= n; i ++){
//我们存储的前缀和是c[i]数组,是数量公式得到的值
c[i] = (long) (n - i) * (n - i - 1) / 2;
s[i] = s[i - 1] + c[i];
}
while(q -- > 0)
{
long k = sc.nextLong(); //找第k小的数字
//开始二分下标
int l = 1, r = n;
while(l < r)
{
int mid = l + r >> 1;
if(s[mid] < k) l = mid + 1;
else r = mid;
}
System.out.println(a[l]);
}
}
}