链接 click
之前重新学了二分,这道题嘛还是不会二分
二分前提是绝对单调,根据体力可以知道每行,每列的单调情况,(每列好像没啥用)
二分是对答案的范围进行二分,最大/小值不是 左下 和 右上 ,因为这个wa了好多次
二分是对答案进行二分,这层二分的check是看看这个答案是不是满足题意,
如果大于题意的话 说明值大了 r=stand-1;
反之,小了 l=stand+1;
之所以有个暴力二分,是check里的是对每一层进行判断(每一层),之后才第二层二分
#include<iostream>
#include<stdio.h>
long long m,n;long long l,r,stand;
long long ij(long long i,long long j)
{
return i*i+j*j+100000*(i-j)+i*j;
}
long long check()
{
long long cnt=0;
for(int i=1;i<=m;++i)
{
int lx=1,rx=m;
while(lx<=rx)
{
int mid=(lx+rx)/2;
if(ij(mid,i)<=stand)
lx=mid+1;
else
rx=mid-1;
}
cnt+=lx-1;
}
return cnt;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld",&m,&n);
l=-(m*m*3+100000*m),r=m*m*3+100000*m;
while(l<=r)
{
stand=(l+r)/2;
if(check()<n)
l=stand+1;
else
r=stand-1;
}
printf("%lld\n",l);
}
return 0;
}