Codeforces Round #256 (Div. 2) D. Multiplication Table

本文介绍了一种利用二分查找算法解决特定问题的方法:在一个n*m的乘法表中查找小于等于某个数n的所有整数个数。通过自定义函数solve()来计算小于等于n的元素数量,并使用二分查找确定目标值的确切位置。

逆向思维,二分查找答案。


对于一个n*m乘法表,要查数字n前有多少小于等于n的,可用

ll solve(ll t){

    ll res=0;
    for(int i=1;i<=n;i++){
            ll tmp=t/i;
            if(tmp>m)
                tmp=m;
            res+=tmp;
    }
    return res;
}

二分时若solve(n)<k则肯定不是想要的n,使l=mid+1,但若solve(n)==k时可能是想要的n,也可能不是(n不一定属于乘法表),所以应令r=mid

代码:

#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
long long n,m,k;
ll solve(ll t){
    ll res=0;
    for(int i=1;i<=n;i++){
            ll tmp=t/i;
            if(tmp>m)
                tmp=m;
            res+=tmp;
    }
    return res;
}

int main(){
    while(~scanf("%I64d%I64d%I64d",&n,&m,&k)){

            ll l=1;
            ll r=n*m+1;
            ll mid;
            while(l<r){
                    mid=(l+r)/2;
                    if(solve(mid)<k)
                       l=mid+1;
                    else
                        r=mid;

            }
            mid=(l+r)/2;
          
            printf("%I64d\n",mid);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值