题目大意:有一个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;
}