2020 CCPC Wannafly Winter Camp Day1 F

孤人 提交于 2020-02-25 22:13:19

2020 CCPC Wannafly Winter Camp Day1 F

题目

在这里插入图片描述

思路

假定这个答案是ANS,那我们就二分ANS,然后对于每一个AiA_i,二分寻找对应的BjB_j,使得AiBj<ANSA_i * B_j \lt ANS,然后统计个数,如果这个数不是K,那么就调整ANS的值就好了,注意讨论负数和0

代码

题解代码

#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cassert>
#include <map>
#include <vector>
using namespace std;
int n, m;
long long K;
const int N = 110000;
vector<int> A[3], B[3];
long long get(long long lim)
{
    if (lim >= 0)
    {
        long long ans = (long long)(A[1].size()) * m + (long long)(B[1].size()) * (n - A[1].size());
        ans += 1ll * A[0].size() * B[2].size() + 1ll * A[2].size() * B[0].size();
        for (int a = 0; a <= 2; a += 2)
        {
            int b = a;
            int now = int(B[b].size()) - 1;
            for (int i = 0; i < A[a].size(); ++i)
            {
                while (now >= 0 && 1ll * A[a][i] * B[b][now] > lim)
                    now--;
                ans += now + 1;
            }
        }
        return ans;
    }
    else if (lim < 0)
    {
        long long ans = 0;
        lim = -lim;
        for (int a = 0; a <= 2; a += 2)
        {
            int b = 2 - a;
            int now = int(B[b].size()) - 1;
            for (int i = 0; i < A[a].size(); ++i)
            {
                while (now >= 0 && 1ll * A[a][i] * B[b][now] >= lim)
                    now--;
                ans += int(B[b].size()) - now - 1;
            }
        }
        return ans;
    }
}
int main()
{
    scanf("%d%d%lld", &n, &m, &K);
    K = 1ll * n * m - K + 1;
    for (int i = 1; i <= n; i++)
    {
        int k1;
        scanf("%d", &k1);
        if (k1 > 0)
            A[0].push_back(k1);
        else if (k1 == 0)
            A[1].push_back(k1);
        else
            A[2].push_back(-k1);
    }
    for (int i = 1; i <= m; i++)
    {
        int k1;
        scanf("%d", &k1);
        if (k1 > 0)
            B[0].push_back(k1);
        else if (k1 == 0)
            B[1].push_back(k1);
        else
            B[2].push_back(-k1);
    }
    for (int i = 0; i < 3; i++)
    {
        sort(A[i].begin(), A[i].end());
        sort(B[i].begin(), B[i].end());
    }
    long long l = 0, r = 2e18, ans = 0, bias = 1e18;
    while (l < r)
    {
        long long mid = (l + r >> 1);
        if (get(mid - bias) >= K)
        {
            ans = mid - bias;
            r = mid;
        }
        else
            l = mid + 1;
    }
    cout << ans << endl;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!