考察:二分

思路:

       首先这道题不是让我们求坐标,而是求具体的值.观察式子,当j不变时,i增大,值增大.分数满足单调性,j不变时,i也满足单调性.二分分数,枚举每一列有多少个满足分数<小于当前score,根据总数再继续二分score.在枚举每一列时,i也满足单调性,所以也用二分枚举i.

注意:二分get(mid,j)<score时,二分结束的值是满足此性质的最大数....不要搞成第一个==score的数....

 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 typedef long long LL; 6 const LL Maxn = 7500000000LL,Minv = -2499859999LL; 7 int n; 8 LL m; 9 LL get(int i,int j)10 {11     LL res = (LL)i*i +100000ll*i + (LL)j*j-100000ll*j+(LL)i*j;12     return res;13 }14 int check(int j,LL score)15 {16     int l = 0,r = n;17     while(l<r)18     {19         int mid = l+r+1>>1;20         if(get(mid,j)<score) l = mid;21         else r = mid-1;22     }23     return r;24 }25 int main() 
26 {27     int T;28     scanf("%d",&T);29     while(T--)30     {31         scanf("%d%lld",&n,&m);32         LL l = Minv,r = Maxn;33         while(l<r)34         {35             LL mid = l+r+1>>1,res = 0;36             for(int i=1;i<=n;i++)37                 res+=check(i,mid);38             if(res<m) l = mid;39             else r = mid-1;40         }41         printf("%lld\n",r);42     }43     return 0;44 }