基准时间限制:1 秒 空间限制:131072 KB 分值: 40
难度:4级算法题
数组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 21 22 33 4
Output示例
9
思路:二分答案。结果的范围在【a[0]*b[0] , a[n-1]*b[n-1]】,二分这个范围的值,然后确定其是否为第K大(第,n*n-k+1小)。
Code:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int AX = 5e4+66;
LL a[AX];
LL b[AX];
LL n , k ;
LL res ;
LL f( LL v ){
LL sum = 0;
LL j = n - 1;
for( int i = 0 ; i < n ; i++ ){
while( j >= 0 ){
if( a[i]*b[j] > v ) j--;
else break;
}
sum += j + 1;
}
return sum >= k ;
}
int main(){
ios::sync_with_stdio(false); cin.tie(0);
cin >> n >> k ;
for( int i = 0 ; i < n ; i++ ){
cin >> a[i] >> b[i];
}
sort( a, a + n );
sort( b, b + n );
k = n * n - k + 1;
LL l = a[0] * b[0];
LL r = a[n-1] * b[n-1];
while( l <= r ){
LL mid = ( l + r ) >> 1;
if( f( mid ) ){
r = mid - 1 ;
}else{
l = mid + 1 ;
}
}
cout << l << endl;
return 0;
}