通过这道题。终于对二分更进一步了解了。
问题问什么,就二分枚举什么,进而判断是否符合而确定答案。
#include <iostream>
using namespace std;
typedef long long ll;
#define inf 1e12
ll n,m; //没有声明long long 调试了N久。
ll fine(ll N,ll a) //再一次二分
{
ll l=0,r=n+1; //由于可以一个也没有,所以这个声明。
while(r-l>1)
{
ll mid=(l+r)>>1;
if(mid*mid+N*N+100000*(mid-N)+N*mid>a)
r=mid;
else
l=mid;
}
return r-1;
}
bool f(ll mid) //检测当前mid为答案时,有多少个数字小于它。
{
ll ans=0;
for(ll i=1;i<=n;i++)
ans+=fine(i,mid);
return ans>=m;
}
int main()
{
int cas;
cin>>cas;
while(cas--)
{
cin>>n>>m;
ll l=-inf,r=inf; //枚举答案。
while(r-l>1)
{
ll mid=l+(r-l)/2;
if(f(mid)) r=mid;
else l=mid;
}
cout<<r<<endl;
}
return 0;
}