题:https://ac.nowcoder.com/acm/contest/3979/F
题意:俩个序列俩俩相乘得到n*m个数,求第k大的数是哪个
分析:二分
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define pb push_back #define lson root<<1,l,midd #define rson root<<1|1,midd+1,r const int M=1e6+6; const ll inf=1e13; ll a[M],b[M]; int n,m; ll k; ll check(ll x){ ll countt=0; for(int i=1;i<=n;i++){///在b数组里找哪些数乘当前a[i]会大于等于x,记录这个数有几个 ll y; if(a[i]<0){ if(x<=0) y=x/a[i]; else y=floor((double)x/(double)a[i]); countt+=upper_bound(b+1,b+1+m,y)-b-1;///要把等于的算进去 } else if(a[i]==0&&x<=0) countt+=m; else if(a[i]>0){ if(x<=0) y=x/a[i]; else y=ceil((double)x/(double)a[i]); countt+=m-(lower_bound(b+1,b+1+m,y)-b-1); } } return countt; } int main(){ scanf("%d%d%lld",&n,&m,&k); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); for(int i=1;i<=m;i++) scanf("%lld",&b[i]); sort(b+1,b+1+m); ll l=-inf,r=inf; while(l<=r){ ll midd=(l+r)>>1; if(check(midd)<k) r=midd-1; else l=midd+1; } printf("%lld ",r); return 0; }