二分 51Nod1105 第K大的数

来源:互联网 发布:本地连接 未识别的网络 编辑:程序博客网 时间:2024/05/29 11:20

传送门:点击打开链接

题意:n<=50000,再给你两个数组A,B,C数组是A[i]*B[j],求第k大

思路:二分。主要想说,,原来在重复的数的有序数组中二分某个数,只要算一次lower_bound就行了- -。。。。

#include<map>#include<set>#include<cmath>#include<ctime>#include<stack>#include<queue>#include<cstdio>#include<cctype>#include<string>#include<vector>#include<cstring>#include<iostream>#include<algorithm>#include<functional>#define fuck(x) cout<<"["<<x<<"]"#define FIN freopen("input.txt","r",stdin)#define FOUT freopen("output.txt","w+",stdout)using namespace std;typedef long long LL;typedef pair<int, int>PII;const int MX = 5e4 + 5;const int INF = 0x3f3f3f3f;int n, k;LL A[MX], B[MX];LL check(LL x) {    LL sum = 0;    for(int i = n; i >= 1; i--) {        int t = lower_bound(B + 1, B + 1 + n, (x - 1) / A[i] + 1) - B;        sum += n - t + 1;        if(sum == 0) break;    }    return sum;}void solve() {    LL l = 1, r = A[n] * B[n], m;    while(l <= r) {        m = (l + r) >> 1;        LL f = check(m);        if(f < k) r = m - 1;        else l = m + 1;    }    printf("%I64d\n", l - 1);}int main() {    //FIN;    while(~scanf("%d%d", &n, &k)) {        for(int i = 1; i <= n; i++) {            scanf("%I64d%I64d", &A[i], &B[i]);        }        sort(A + 1, A + 1 + n);        sort(B + 1, B + 1 + n);        solve();    }    return 0;}


0 0
原创粉丝点击