51Nod-1105-第K大的数

来源:互联网 发布:犀牛软件分割模型 编辑:程序博客网 时间:2024/06/05 12:04

ACM模版

描述

描述

题解

这里使用二分套二分查找即可。一般的二分查找是通过下标范围查找,而二分套二分是为了求两个数组组合乘积的问题,查找第K大的值,这里我们需要通过数据的范围查找,而不是下标的范围,这里需要两次快排。

需要强调的一点是数据范围问题!!!一定要使用long long型,避免数据溢出!!!

代码

#include <iostream>#include <algorithm>#include <cstdio>/* *  二分套二分 *  数组A同数组B组合乘积,二分查找第K大 */typedef long long ll;using namespace std;const int MAXN = 5e4 + 10;ll N, K;ll A[MAXN];ll B[MAXN];//  查找小于x的元素个数ll check(ll x){    ll j = N, ans = 0;    for (int i = 1; i <= N; i++)    {        for (; j > 0;)        {            if (A[i] * B[j] > x)            {                j--;            }            else            {                break;            }        }        ans += j;    }    return ans;}int main(int argc, const char * argv[]){    cin >> N >> K;    for (int i = 1; i <= N; i++)    {        scanf("%lld %lld", A + i, B + i);    }    sort(A + 1, A + N + 1);    sort(B + 1, B + N + 1);    ll ans = 0;    ll key = N * N - K + 1;    ll low = A[1] * B[1];   //  初始最小值    ll high = A[N] * A[N];  //  初始最大值    while (high - low > 1)    {        ll mid = (low + high) >> 1;        if (check(mid) >= key)        {            ans = mid;            high = mid;        }        else        {            low = mid;        }    }    cout << ans << '\n';    return 0;}

参考

《二分查找》

0 0