码迷,mamicode.com
首页 > 其他好文 > 详细

ACM第K大数——双二分

时间:2014-12-12 20:56:48      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:style   sp   for   strong   on   size   acm   br   方法   

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;

ACM第K大数——双二分

标签:style   sp   for   strong   on   size   acm   br   方法   

原文地址:http://blog.csdn.net/colorwaterer/article/details/41898235

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!