POJ-3685-二分

来源:互联网 发布:淘宝双十一报名入口 编辑:程序博客网 时间:2024/05/23 23:29

题目大意:有一个n*n的矩阵,第i行第j列元素的值为i*i+100000*i+j*j-100000*j+i*j;问第m大的元素是什么;

题目解析:注意到如果j确定的话,那么函数就是关于i的增函数,所以可以二分再二分;

AC代码:

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>using namespace std;typedef long long ll;ll n,m;ll fun(ll x,ll y){    return x*x+100000*x+y*y-100000*y+x*y;}bool ok(ll t){    ll cnt=0;    for(ll j=1;j<=n;j++)    {        ll l=1;        ll r=n,ans=0;        while(l<=r)        {            ll mid=(l+r)>>1;            if(l==0&&r==0)            {                ans=0;                break;            }            if(fun(mid,j)<=t)            {                ans=mid;                l=mid+1;            }            else            {                r=mid-1;            }        }        cnt+=ans;    }    return cnt>=m;}int main(){    int cas;    scanf("%d",&cas);    while(cas--)    {        scanf("%lld%lld",&n,&m);        ll l=-100000*n,r=2*n*n+100000*n,ans;        while(l<=r)        {            ll mid=(l+r)>>1;            if(ok(mid))            {                ans=mid;                r=mid-1;            }            else            {                l=mid+1;            }        }        printf("%lld\n",ans);    }    return 0;}



0 0
原创粉丝点击