ACM第K大數——雙二分

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;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章