51nod 1105---二分套二分

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1105

题意a序列和b序列,ab序列是 a和b两两组合,问你ab中第k大是多少。。

这题是个二分套二分,是个二分好题。。为什么好呢,因为这个二分容易写残疾啊。。。(总之就是我太弱了

接下来分析一下这个题的解法和要注意的地方。

一个显然的方法就是二分答案了,然后判断mid是第几大就可以了。。

但是,仔细一想?咦。。会不会二分的答案其实不是ab数组里面的呢?会不会ab里面有很多个一样的值我无法返回正确答案呢?

我们先分析二分时候我们计算的是什么。。

我们计算的mid在ab数组里面时候,枚举a,二分b就可以知道有几个大于等于mid了,

在设计二分的时候-当返回值大于等于k的时候,使得l=mid+1;(参考blog--《你真的会二分查找吗?》

我们这时候考虑一下我们会遇到的问题,

Q 计算的时候会不会有什么问题?例如mid不是ab数组里面的一个数。

A 我们先不考虑是不是ab数组里的一个数,我们计算的是比mid大的ab中的数有多少个。

Q     如果一个数是第k大但是这个数有很多呢?

A     (参考blog--《你真的会二分查找吗?》),这里返回第一个大于等于它的值。

Q  会不会返回一个不在ab数组里的一个数呢?

A 答案是不会的,因为
这个问题可以划归到上一个问题,既然返回的是第一个大于等于它的值,那么如果mid不合法,那么一定存在一个和mid计算值一样的,并且这个合
法值要小于mid,(因为不存在的时候要向上取整的,自然虽然计算值一样但是存在的较小)。。

PS。。很多地方可能说的不对,望大家指正。

放代码:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

const int maxn=50000;
long long n,k;
long long A[maxn],B[maxn];

long long Ca(long long x){
    long long f;
    long long ret1=0;
    for(int i=0;i<n;i++){
        f=x/A[i];
        if(x%A[i]!=0)
            f++;
        if(B[n-1]>=f)
            ret1+=(n-(long long)(lower_bound(B,B+n,f)-B));
    }
    return ret1;
}

int main()
{
    cin>>n>>k;
    for(int i=0;i<n;i++){
        cin>>A[i]>>B[i];
    }
    sort(A,A+n);
    sort(B,B+n);
    long long l=A[0]*B[0],r=A[n-1]*B[n-1],mid;
    while(l<=r){
        mid=(l+r)/2;
        long long x=Ca(mid);
        if(x>=k){
            l=mid+1;
        }
        else{
            r=mid-1;
        }
    }
    cout<<l-1<<endl;
    return 0;
}
时间: 2024-10-08 14:54:05

51nod 1105---二分套二分的相关文章

POJ 3685 二分套二分

Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i2 + 100000 × i + j2 - 100000 × j + i × j, you are to find the M-th smallest element in the matrix. Input The first line of input is the number of test

POJ-3579 Median---二分第k大(二分套二分)

题目链接: https://cn.vjudge.net/problem/POJ-3579 题目大意: 求的是一列数所有相互之间差值的序列的最中间的值是多少. 解题思路: 可以用二分套二分的方法求解第m大,和POJ-3685类似,这里的模板也差不多 枚举第m大x,判断小于等于x的数目是不是大于m,如果大于m说明x >= 第m大,调整区间r = mid - 1 不然l = mid + 1 此处是大于m而不是小于m是因为一个数可能出现多次,那么小于等于中间的数目可能就比m大 在计算小于等于x的数目的时

二分套二分 hrbeu.acm.1211Kth Largest

Kth Largest TimeLimit: 1 Second   MemoryLimit: 32 Megabyte Description There are two sequences A and B with N (1<=N<=10000) elements each. All of the elements are positive integers. Given C=A*B, where '*' representing Cartesian product, c = a*b, whe

poj3685 二分套二分

F - 二分二分 Crawling in process... Crawling failed Time Limit:6000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Status Description Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i2

POJ 3685 二分套二分(水题

题意:给出一个N*N的矩阵A,A[i][j]的值等于i2 + 100000 ×i + j2 - 100000 × j + i × j,求这个矩阵中第M小的数 代码: 1 #include <cstdio> 2 #include <iostream> 3 using namespace std; 4 long long N; 5 long long cal(long long i,long long j){ 6 return i*i+100000*i+j*j-100000*j+i*j

POJ 3685 Matrix 二分套二分

POJ 3685 Matrix 二分 题意 有一个N阶方阵,方正中第i行第j列的元素值为\(d_{i,j}=i^{2}+1e5*i+j^{2}-1e5*j+i*j\),我们需要找出这个方阵中第M小的元素值. 解题思路 分析这个公式,我们发现:当j固定的时候,这个公式关于i(取值范围:从0到n)是单调增加的,所以这里我们可以二分一个答案,然后一列一列的找小于(等于)它的个数,这样加起来我们就能知道我们枚举的这个答案是第几小了. 需要注意的是,第一个最外层的二分有点不同,因为我们二分的答案可能不存在

51nod 1105 二分好题

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1105 1105 第K大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 数组A和数组B,里面都有n个整数.数组C共有n^2个整数,分别是A[0] * B[0],A[0] * B[1] ......A[1] * B[0],A[1] * B[1]......A[n - 1] * B[n - 1](数组A同数组B的组合).求

【CF739E】Gosha is hunting(WQS二分套WQS二分)

点此看题面 大致题意: 你有两种捕捉球(分别为\(A\)个和\(B\)个),要捕捉\(n\)个神奇宝贝,第\(i\)个神奇宝贝被第一种球捕捉的概率是\(s1_i\),被第二种球捕捉的概率是\(s2_i\),问在最优策略下期望捕捉到的神奇宝贝数量. \(WQS\)二分 这应该是一道比较经典的\(WQS\)二分题(毕竟是 \(WQS\)二分套\(WQS\)二分). \(WQS\)二分套\(WQS\)二分 如果你知道\(WQS\)二分,应该就不难想到\(WQS\)二分一个代价\(C1\),表示每使用一

LibreOJ #2006. 「SCOI2015」小凸玩矩阵 二分答案+二分匹配

#2006. 「SCOI2015」小凸玩矩阵 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 小凸和小方是好朋友,小方给小凸一个 N×M N \times MN×M(N≤M N \leq MN≤M)的矩阵 A AA,要求小凸从其中选出 N NN 个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的 N NN 个数中第 K KK 大的数字的最小值是多少. 输入格式 第一行给出三个整数