Problem
数组A和数组B,里面都有n个整数。数组C共有n^2个整数,分别是A[0] * B[0],A[0] * B[1] ......A[1] * B[0],A[1] * B[1]......A[n - 1] * B[n - 1](数组A同数组B的组合)。求数组C中第K大的数。
例如:A:1 2 3,B:2 3 4。A与B组合成的C包括2 3 4 4 6 8 6 9 12共9个数。
Input
第1行:2个数N和K,中间用空格分隔。N为数组的长度,K对应第K大的数。(2 <= N <= 50000,1 <= K <= 10^9)
第2 - N + 1行:每行2个数,分别是A[i]和B[i]。(1 <= A[i],B[i] <= 10^9)
Output
输出第K大的数。
Input 示例
3 2
1 2
2 3
3 4
Output 示例
9
分析
首先,我们将a, b两个数组分别排序从小到大。
那么a[0]*b[0]是最小值min, a[n-1]*b[n-1]是最大值max。
设mid=(min+max)/2, 那么我们求一下a*b的结果中有多少个数是>=mid的,假设num个,若num>=k,那么答案一定在[mid + 1, max]之间,那么我们令min=mid + 1, s = mid; 若num < k,那么答案一定在[min, mid - 1]之间,那么我们令max = mid - 1.
这样一步步缩小区间,直到min > max时,s即为答案。
这里我们二分了最大值与最小值的范围,那么另一个二分在哪呢?
思考一下。。。
怎么求a*b的结果中有多少个数是>=mid的?
1、两层for遍历a, b数组求出所有的答案再跟mid比较计算出num行吗?
对于第一种方法,肯定是要超时的。
2、那么我们可以这样,外面这层for(i)遍历a数组,里面那层用二分法来遍历b数组。当二分查找到编号为x的那个值b[x]+a[i]>=mid且b[x-1]+a[i]<mid, 那么num+=n-x;