码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3685 Matrix 二分套二分

时间:2020-02-03 20:47:38      阅读:67      评论:0      收藏:0      [点我收藏+]

标签:ack   space   value   mes   tps   string   iostream   tmp   题意   

POJ 3685 Matrix 二分

题意

有一个N阶方阵,方正中第i行第j列的元素值为\(d_{i,j}=i^{2}+1e5*i+j^{2}-1e5*j+i*j\),我们需要找出这个方阵中第M小的元素值。

解题思路

分析这个公式,我们发现:当j固定的时候,这个公式关于i(取值范围:从0n)是单调增加的,所以这里我们可以二分一个答案,然后一列一列的找小于(等于)它的个数,这样加起来我们就能知道我们枚举的这个答案是第几小了。

需要注意的是,第一个最外层的二分有点不同,因为我们二分的答案可能不存在,但是也是符合第m小,这个情况还是需要注意的,这里需要参看关于二分的第四种形式。二分链接

代码实现

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<stack>
#include<queue>
#include<map>
typedef long long ll;
using namespace std;
const double esp=1e-6;
const int inf=0x3f3f3f3f;
const int MAXN=1E6+7;
ll n, m;
ll fun(ll i, ll j)
{
    return i*i+100000*i+j*j-100000*j+i*j;
}
void dis()
{
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            printf("%lld ", fun(i, j));
        }
        printf("\n");
    }
}
ll solve(ll value)
{
    ll sum=0;
    for(ll j=1; j<=n; j++)
    {
        ll left=0, right=n+1, ans=0;
        while(left < right)
        {
            ll mid=left+(right-left)/2;
            if(fun(mid, j) <= value)
                left=mid+1;
            else right=mid;
        }
        if(left!=0)
            sum+=left-1;
    }
    return sum;
}
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%lld%lld", &n, &m);
//      dis();
        ll lt=-1e12, rt=1e12, ans;
        while(lt+1 < rt) //这里的二分我们提前是不知道该向左侧还是右侧前进的。
        {
            ll mid = lt + (rt-lt)/2;
            ll tmp=solve(mid);
            if(tmp >= m)
            {
                ans=mid;
                rt=mid;
            }
            else lt=mid;
        }
        printf("%lld\n", ans);  
    }
    return 0;
}

POJ 3685 Matrix 二分套二分

标签:ack   space   value   mes   tps   string   iostream   tmp   题意   

原文地址:https://www.cnblogs.com/alking1001/p/12257226.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!