POJ3685Matrix(二分套二分)

传送门

题目大意:N*N的矩阵,a[i][j]=i*i+100000*i+j*j-100000*j+i*j,求矩阵中第K小。

N<=5*10^4

题解:

打个表,发现每一列从上往下单调递增。

在大范围内二分搜索,二分第k小为x,然后再二分找矩阵中有多少个比x小的数。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long 
using namespace std;

int T;

LL n,m;

LL cal(LL x,LL y)
{
    return x*x+100000*x+y*y-100000*y+x*y;
}

LL slove(LL x)
{
    LL js=0;
    for(int i=1;i<=n;i++)
    {
        int cnt=0;
        int ll=1,rr=n;
        while(ll<=rr)
        {
            int mmid=(ll+rr)>>1;
            if(cal(mmid,i)<=x) cnt=mmid,ll=mmid+1;
            else rr=mmid-1;
        }
        js=js+cnt; 
    }
    return js;
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld",&n,&m);
        LL ans,l=-(1e12),r=1e12;
        while(l<=r)
        {
            LL mid=(l+r)>>1;
            if(slove(mid)>=m) ans=mid,r=mid-1;
            else l=mid+1;
        }
        cout<<ans<<endl;
    }
    return 0;
} 

猜你喜欢

转载自www.cnblogs.com/zzyh/p/11986083.html
今日推荐