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 }