题目传送门

sol:二分答案$K$,算大于$K$的乘积有多少个。关键在于怎么算这个个数,官方题解上给出的复杂度是$O(nlogn)$,那么计算个数的复杂度是$O(n)$的。感觉写着有点困难,自己写了一个复杂度是$O(nlog^{2}n)$,也够AC了。有正有负,控制边界有点难度。

  • 二分答案

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> PII;
    const int MAXN = 1e5 + ;
    int a[MAXN], b[MAXN];
    int n, m; LL k;
    LL check(LL mid) {
    LL sum = ;
    for (int i = ; i <= n; i++) {
    if (a[i] == ) {
    if (mid < ) sum += m;
    continue;
    }
    if (a[i] > ) {
    if (mid >= ) {
    sum += b + + m - upper_bound(b + , b + + m, mid / a[i]);
    } else {
    sum += b + + m - lower_bound(b + , b + + m, (mid + ) / a[i]);
    }
    } else {
    if (mid >= ) {
    sum += lower_bound(b + , b + + m, mid / a[i]) - - (b + - );
    } else {
    sum += upper_bound(b + , b + + m, (mid + ) / a[i]) - - (b + - );
    }
    }
    }
    return sum;
    }
    int main() {
    scanf("%d%d%lld", &n, &m, &k);
    for (int i = ; i <= n; i++) scanf("%d", &a[i]);
    for (int i = ; i <= m; i++) scanf("%d", &b[i]);
    sort(b + , b + + m);
    LL l = -1e12 - , r = 1e12 + ;
    while (l + < r) {
    LL mid = l + r >> ;
    if (check(mid) < k) r = mid;
    else l = mid;
    }
    printf("%lld\n", r);
    return ;
    }
04-28 17:45