Multiplication Table

题目链接
题意:
给出一个f[i][j]=i*j(1≤i≤n,1≤j≤m)的数组,将该数组内所有数(包含重复的)从小到大排序后的第k个数
思路:
很显然的二分性,在这n行中,每一行都是单调递增的,对于一个数x,我们可以很容易找出所有数字中比x小的个数,即累加每一行比x小的数字即可。我们二分x即可得出答案。具体实现见代码。

点击查看代码
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define ll long long 
const int N = 2e5+5;
int n,m;
int hanshu(int mid,int x){
    int y=mid/x;
    if(mid%x==0){
        return min(m,y-1);
    }
    return min(y,m);
}
void solve(){
    cin>>n>>m;
    int k;
    cin>>k;
    int l=1,r=n*m;
    while(l<=r){
        int mid=(l+r)>>1;
        int sum=0; //记录比mid严格小的数的个数
        int f=0; //f表示乘法表里mid的个数
        for(int i=1;i<=n;++i){
            sum+=hanshu(mid,i);
            if(mid%i==0&&mid/i<=m) f++;
        }
        if(sum>=k){
            r=mid-1;
        }else{
            if(sum+f>=k){
                cout<<mid<<endl;
                return ;
            }else{
                l=mid+1;
            }
        }
    }
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int _=1;
    // cin>>_;
    while(_--)
    solve();
    return 0;
}
posted @   sjgigj  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示