第K小数

源代码:

#include<cstdio>
#include<algorithm>
#define LL long long
using namespace std;
LL n,m,k,i1[200001],i2[200001];
bool Check(LL T)
{
    LL Sum=0,Num=m;
    for (int a=1;a<=n;a++)
    {
        while (Num>=1&&i1[a]*i2[Num]>T)
          Num--;
        Sum+=Num;
    }
    return Sum>=k;
}
int main()
{
    scanf("%lld%lld%lld",&n,&m,&k);
    for (int a=1;a<=n;a++)
      scanf("%lld",&i1[a]);
    for (int a=1;a<=m;a++)
      scanf("%lld",&i2[a]);
    sort(i1+1,i1+n+1);
    sort(i2+1,i2+m+1);
    LL Left=i1[1]*i2[1],Right=i1[n]*i2[m],Ans=0;
    while (Left<=Right) //二分答案。
    {
        LL Mid=(Left+Right)>>1;
        if (Check(Mid))
        {
            Ans=Mid;
            Right=Mid-1;
        }
        else
          Left=Mid+1;
    }
    printf("%lld",Ans);
    return 0;
}

/*
    挺有趣的一道题。
    因为二分答案可以转化为求最中最的问题,那么正好,我们只需要二分答案,然后检验有多少个更小的就好了。
    但是单调性难以看出。
    i1[]正序循环;
        i2[]*i1[]>T,倒序循环;
    其实仔细想一想,i1[]后面肯定更大,这样就找出了所有更小的数。
*/
原文地址:https://www.cnblogs.com/Ackermann/p/6050716.html