2020 CCPC Wannafly Winter Camp Day1 F 乘法 (二分)

题目链接
在这里插入图片描述
思路:很容易想到二分,只不过我的解法和题解不太一样,貌似复杂度还高一点点?不过也算一个方法吧,就是先将b数组排序,二分一个值以后,遍历每一个ai,查找b数组里有多少个数乘以ai会大于等于mid,只不过在ai为0,正数、负数的话情况是不一样的,讨论一下就行,不过细节确实也挺烦的,lower_bound边界调到崩溃QAQ。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+1;
int n,m;
ll k,a[maxn],b[maxn];
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=-1e12,r=1e12;
    while(l<=r)
    {
        ll mid=(l+r)>>1;
        ll cnt=0;
        for(int i=1;i<=n;++i)//接下来就是要在b数组里找哪些数乘当前a[i]会大于等于mid,记录这个数有几个
        {
            ll t;
            if(a[i]<0)
            {
                if(mid<=0) t=mid/a[i];
                else t=((mid-1)/a[i])-1;//这里为什么t会不一样的原因最好自己手写算一下
                cnt+=upper_bound(b+1,b+1+m,t)-b-1;
             }
             else if(a[i]==0&&mid<=0) cnt+=m;
             else if(a[i]>0)
             {
                if(mid<=0) t=mid/a[i];
                else t=((mid-1)/a[i])+1;
                cnt+=(b+m+1-lower_bound(b+1,b+1+m,t));
             }
        }
        if(cnt<k) r=mid-1;
        else l=mid+1;
    }
    printf("%lld\n",r);
}
发布了39 篇原创文章 · 获赞 0 · 访问量 1067

猜你喜欢

转载自blog.csdn.net/qq_42479630/article/details/104072320