码迷,mamicode.com
首页 > 其他好文 > 详细

poj3685 Matrix 二分 函数单调性

时间:2014-09-14 20:43:07      阅读:249      评论:0      收藏:0      [点我收藏+]

标签:des   blog   io   os   ar   strong   for   div   sp   

 

  Memory Limit: 65536K
Total Submissions: 4637   Accepted: 1180

Description

Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i2 + 100000 × i + j2 - 100000 × j + i × j, you are to find the M-th smallest element in the matrix.

Input

The first line of input is the number of test case.
For each test case there is only one line contains two integers, N(1 ≤ N ≤ 50,000) and M(1 ≤ M ≤ N × N). There is a blank line before each test case.

Output

For each test case output the answer on a single line.

Sample Input

12

1 1

2 1

2 2

2 3

2 4

3 1

3 2

3 8

3 9

5 1

5 25

5 10

Sample Output

3
-99993
3
12
100007
-199987
-99993
100019
200013
-399969
400031
-99939

思路:
1 可以看出当j确定的时候i是单调递增的,那么就可以二分得到某个值当j确定时有多少i的值大于它,设为big
2 二分答案当big+ind>n*n(也即全部个数)时,这个值就太小了,增加下界,反之减少上界即可
错误原因 1:全部个数忘了n*n,打成n了 2:上下界错误,看成了1e4 3:读取爆longlong
#include <cstdio>
using namespace std;

long long ind,n;
long long equ(long long i,long long j){
    return i*i+j*j+i*j+(i-j)*100000;
}
long long judge(long long mid){
    long long big=0;
    for(int j=1;j<=n;j++){
        int l=0;
        int r=n+1;
        long long cp;
        while(r-l>1){
            int m=(r+l)>>1;
            cp=equ(m,j);
            if(cp==mid){
                l=m;
                break;
            }
            else if(cp<mid){
                l=m;
            }
            else{
                r=m;
            }
        }
 //       printf("binary %I64d col %d %I64d\n",mid,j,l);
        big+=n-l;
    }
    return big;
}
void printe(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            printf("%6I64d ",equ(i,j));
        }
        puts("");
    }
}
int main(){
    int T;
   // freopen("C:\\Users\\Administrator\\Desktop\\input.txt","r",stdin);
    scanf("%d",&T);
    while(T--){
        scanf("%I64d%I64d",&n,&ind);
        long long l=-(3*n*n+n*300000),r=-l;
        //printe();
        while(r-l>1){
            long long mid=l+r>>1;
            long long big=judge(mid);
            if(big>n*n-ind){
                l=mid;
            }
            else {
                r=mid;
            }
        }
        printf("%I64d\n",r);
    }
    return  0;
}

  

poj3685 Matrix 二分 函数单调性

标签:des   blog   io   os   ar   strong   for   div   sp   

原文地址:http://www.cnblogs.com/xuesu/p/3971539.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!