基准时间限制:1 秒 空间限制:131072 KB
数组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
思路:二分,先排序,首先二分答案,答案的范围在ans[0]*bns[0]---ans[n-1]*bns[n-1]之间,然后二分统计这个答案的前面是否有大于等于k个比他大的,符合的话并且二分检查这个答案是否存在。
1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<string.h> 5 #include<queue> 6 #include<math.h> 7 #include<set> 8 #include<vector> 9 #include<string.h> 10 using namespace std; 11 typedef long long LL; 12 typedef struct node { 13 LL x; 14 LL y; 15 } ss; 16 LL ans[60000]; 17 LL bns[60000]; 18 bool check(LL n,LL N,LL M) { 19 int i,j; 20 LL cnt = 0; 21 for(i = 0; i < N; i++) { 22 int l = 0; 23 int r =N; 24 int id = -1; 25 while(l<=r) { 26 int mid = (l+r)/2; 27 if(bns[mid]*ans[i]>=n) { 28 id = mid; 29 r = mid - 1; 30 } else l= mid + 1; 31 } 32 if(id!=-1) { 33 if(n==12)printf("%d ",id); 34 cnt += N-id; 35 } 36 } 37 if(cnt>=M)return true; 38 return false ; 39 } 40 bool er(int n,int m,int ask); 41 bool test(LL mid,LL N,LL M); 42 int main(void) { 43 LL N,M; 44 scanf("%lld %lld",&N,&M); 45 int i,j; 46 for(i = 0; i < N; i++) { 47 scanf("%lld %lld",&ans[i],&bns[i]); 48 } 49 sort(ans,ans+N); 50 sort(bns,bns+N); 51 LL ak = ans[0]*bns[0]; 52 LL bk = ans[N-1]*bns[N-1]; 53 LL all = -1;//printf("%lld %lld ",ak,bk); 54 while(ak<=bk) { 55 LL mid = (ak+bk)/2; 56 if(check(mid,N,M)) { 57 if(test(mid,N,M)) 58 all = max(mid,all); 59 ak = mid + 1; 60 } else bk = mid-1; 61 } 62 printf("%lld ",all); 63 return 0; 64 } 65 bool test(LL mid,LL N,LL M) { 66 int i,j; 67 LL kk; 68 for(i = 0; i < N; i++) { 69 if(mid%ans[i]==0) { 70 if(er(0,N,mid/ans[i])) 71 return true; 72 } 73 } 74 } 75 bool er(int n,int m,int ask) { 76 if(n>m)return false; 77 int mid = (n+m)/2; 78 if(bns[mid]==ask) { 79 return true; 80 } else if(bns[mid]>ask) { 81 return er(n,mid-1,ask); 82 } else return er(mid+1,m,ask); 83 }
复杂度N*log(N);