zoukankan      html  css  js  c++  java
  • POJ 3685 Matrix 二分 函数单调性 难度:2

      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;
    }
    

      

  • 相关阅读:
    fms服务器端呼叫客户端
    Linux C取整的方法
    fms客户端呼叫服务器端
    Tree Control DataProviders
    IE7下的css style display的兼容处理
    Maxthon,TheWorld,MyIE等多标签浏览器的Flash缓存问题
    Android深入浅出系列之实例应用—弹出消息Toast对象的使用纯文本方式(一)
    C#温故而知新学习系列之XML编程—Xml读取器XmlReader类(二)
    一步一个脚印学习WCF系列之WCF概要—生成元数据与代理(五)
    Eclipse 常用快捷键(转)
  • 原文地址:https://www.cnblogs.com/xuesu/p/3971539.html
Copyright © 2011-2022 走看看