Matrix POJ - 3685

原题链接

考察:二分

思路:

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

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

二刷表示:真的不要在二分里判定用<=,相等的不能计入.

还有就是想的第一次二分枚举i+j的和,第二次枚举j再二分i,但这样难计入是第x个大值.

 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 }

 

posted @ 2021-03-06 00:28  acmloser  阅读(38)  评论(0编辑  收藏  举报