1105 第K大的数(二分)
Posted happy_code
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1105 第K大的数(二分)相关的知识,希望对你有一定的参考价值。
基准时间限制: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 2
1 2
2 3
3 4
Output示例
9
//将两个数组排序后,二分答案,因为对于 A 中每个数,B 乘之也是单调的,所以又可以二分
所以,O(log(1e18)*n*lg(n)) 即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define MOD 1000000007 4 #define INF 0x3f3f3f3f 5 #define eps 1e-9 6 #define LL long long 7 #define MX 50005 8 9 LL n,k; 10 LL A[MX], B[MX]; 11 12 LL check(LL x) 13 { 14 int j = n; 15 LL tot=0; 16 for(int i=1;i<=n;i++) 17 { 18 while(j>0) 19 { 20 if (A[i]*B[j]>x) 21 j--; 22 else 23 break; 24 } 25 tot+=j; 26 } 27 return tot; 28 } 29 30 int main() 31 { 32 while (scanf("%lld%lld",&n,&k)!=EOF) 33 { 34 for (int i=1;i<=n;i++) 35 scanf("%lld%lld",A+i,B+i); 36 sort(A+1,A+1+n); 37 sort(B+1,B+n+1); 38 LL key = n*n-k+1; 39 LL l = A[1]*B[1] ,r = A[n]*B[n]; 40 LL ans; 41 while (l<=r) 42 { 43 LL mid = (l+r)>>1; 44 if (check(mid)>=key) 45 { 46 r = mid-1; 47 ans = mid; 48 } 49 else l = mid+1; 50 } 51 printf("%lld\n",ans); 52 } 53 return 0; 54 }
以上是关于1105 第K大的数(二分)的主要内容,如果未能解决你的问题,请参考以下文章