二分嵌套二分的 二分题-POJ3685- Matrix

题目

思路

这道题,通过观察可以发现公式可知,每一列都是单调递增的,但是每一行不一定单调的。所以,我们首先二分答案 m i d mid mid,然后按列枚举,在每一列中,因为具有单调性,从而可以二分出每一列中数值小于等于 m i d mid mid的数量,然后能够根据整个矩阵中计算出的 ≤ \leq mid的数量,进行二分答案。
注意:

  1. 最外层二分答案的时候,是要寻找满足条件的下界
  2. 里面嵌套的二分,是要寻找到满足条件的上界
  3. 这两个二分在代码的写法上有所不同

代码

(PS:POJ的c++真坑,好多好用的语法都不能用了,QAQ)

ll Cf(ll i,ll j){
    return i * i + 100000ll * i + j * j - 100000ll * j + i * j;
}
ll Ccheck(ll mid,int n){
    ll cnt = 0;
    for (int j = 1; j <= n; j++) {
        ll l = 0, r = n;//二分一列中,有多少元素小于等于mid,这里的二分是二分满足条件的上限
        ll ans = 0;
        while (l <= r) {
            ll i = l + (r - l) / 2;
            if (Cf(i, j) <= mid) {
                ans = i;
                l = i + 1;
            } else r = i - 1;
        }
        cnt += ans;
    }
    return cnt;
}
void C() {
    //二分套二分
    int t;
    cin >> t;
//    auto f = [](ll i, ll j) -> ll {
//        return i * i + 100000ll * i + j * j - 100000ll * j + i * j;
//    };
//    auto check = [&f](ll mid, int n) {
//        //矩阵中有多少小于等于mid的元素
//        //先枚举列,然后再次二分行
//        ll cnt = 0;
//        for (int j = 1; j <= n; j++) {
//            ll l = 0, r = n;//二分一列中,有多少元素小于等于mid,这里的二分是二分满足条件的上限
//            ll ans = 0;
//            while (l <= r) {
//                ll i = l + (r - l) / 2;
//                if (f(i, j) <= mid) {
//                    ans = i;
//                    l = i + 1;
//                } else r = i - 1;
//            }
//            cnt += ans;
//        }
//        return cnt;
//    };
    while (t--) {
        ll n, m;
        cin >> n >> m;
        ll l = -1e12, r = 1e12;
        while (l < r) {
            //cout<<l<<r<<endl; //这里的二分是满足条件的下界
            ll mid = l + (r - l) / 2;
            if (Ccheck(mid, n) < m) {
                l = mid + 1;
            } else r = mid;
        }
        cout << l << endl;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值