![](https://images2015.cnblogs.com/blog/912373/201611/912373-20161110140321374-987891710.png)
![](https://images2015.cnblogs.com/blog/912373/201611/912373-20161110140429702-216507820.png)
![](https://images2015.cnblogs.com/blog/912373/201611/912373-20161110140523295-902068115.png)
源代码:
#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[]后面肯定更大,这样就找出了所有更小的数。
*/