1105 第K大的数

1105 第K大的数

数组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

思路:开始没看清K的范围,不然可以用优先队列,这里用2个二分
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=50004;
 5 
 6 ll n,m;
 7 ll a[N],b[N];
 8 
 9 ll hh(int y,ll x){
10     int l=1,r=n,mid;
11     int ans=1;
12     while(l<=r){
13             mid=(l+r)>>1;
14         if(a[y]*b[mid]>=x){
15             ans=mid;r=mid-1;
16         }
17         else l=mid+1;
18     }
19     return ans;
20 }
21 ll check(ll x){
22     ll sum=0;
23     for(int i=1;i<=n;i++){
24         if(a[i]*b[n]<x) continue;
25         sum+=n-hh(i,x)+1;
26     }
27     return sum;
28 }
29 int main(){
30     scanf("%lld%lld",&n,&m);
31     for(int i=1;i<=n;i++){
32         scanf("%lld%lld",&a[i],&b[i]);
33     }
34     sort(a+1,a+1+n);sort(b+1,b+1+n);
35     ll l=a[1]*b[1]-1,r=a[n]*b[n]+1;;
36     ll ans=0;
37     while(l<=r){
38         ll mid=(l+r)>>1;
39 
40         if(check(mid)>=m){
41             l=mid+1;
42             ans=mid;
43         }
44         else r=mid-1;
45        
46     }
47     printf("%lld\n",ans);
48 }

 

posted on 2017-06-19 19:46  hhhhx  阅读(249)  评论(0编辑  收藏  举报

导航