• Day3-P


    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

    思路:观察列递增,行递减,枚举列进行二分算出第M大,然后二分枚举X是第几大,二分套二分,代码如下:
    typedef long long LL;
    
    const LL INF = 0x3f3f3f3f3f3f3;
    
    LL N, M;
    
    LL calculate(LL i, LL j) {
        return i * i + 100000 * i + j * j - 100000 * j + i * j;
    }
    
    LL check(LL num) {
        LL sum = 0, l, r, mid;
        for (int i = 1; i <= N; ++i) {
            l = 1, r = N;
            while(l <= r) {
                mid = (r + l) >> 1;
                if(calculate(mid,i) > num) {
                    r = mid - 1;
                }
                else
                    l = mid + 1;
            }
            sum += r;
        }
        return sum;
    }
    
    int main() {
        LL T;
        scanf("%I64d", &T);
        while(T--) {
            scanf("%I64d%I64d", &N, &M);
            LL l = -INF, r = INF, mid;
            while(l <= r) {
                mid = (r + l) >> 1;
                if(check(mid) < M) {
                    l = mid + 1;
                }
                else
                    r = mid - 1;
            }
            printf("%I64d
    ", l);
        }
        return 0;
    }
    View Code

     小结:如何寻找二分的答案,如果mid是所求答案,那么check(mid)为true,更新r的值为mid-1,之后的check都是false,从而更新l,最后l变为mid,输出mid。

     比如>=的情况就是true的情况,所以一般答案都是非>=的那一侧。

    补:
    在二分时,注意满足的条件是满足题意还是不满足题意,New如下:(一般来说ans都在等于的那一侧,但是哪一侧是l哪一侧是r需要判断
    typedef long long LL;
    
    LL N, M, mid, ans;
    
    LL calculate(LL i, LL j) {
        return i * i + 100000 * i + j * j - 100000 * j + i * j;
    }
    
    LL check(LL x) {
        LL l, r, mid, sum = 0, ans;
        for(int i = 1; i <= N; ++i) {
            l = 1, r = N, ans = 0;
            while(l <= r) {
                mid = (r + l) >> 1;
                if(calculate(mid, i) <= x) {
                    ans = mid;
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
                    
            }
            sum += ans;
        }
        return sum;
    }
    
    const LL INF = 0x3f3f3f3f3f3f3;
    int main() {
        int T;
        scanf("%d", &T);
        while(T--) {
            scanf("%I64d%I64d", &N, &M);
            //LL l = calculate(1, N), r = calculate(N, 1);
            LL l = -INF, r = INF;
            while(l <= r) {
                mid = (r + l) >> 1;
                if(check(mid) < M) {
                    l = mid + 1;
                } else {
                    ans = mid;
                    r = mid - 1;
                }
            }
            printf("%I64d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    unbuntu下安装flash插件
    ssh命令:使用密钥文件进行登陆
    eclipse关掉jsp,js的语法验证
    spring源码学习之:xml标签扩展配置例子
    spring源码学习之:xml配置文件标签自定义
    java多线程之:线程对象一些api
    java多线程之:Java中的ReentrantLock和synchronized两种锁定机制的对比 (转载)
    Spring Cloud(十):服务网关zuul(转)
    数据库连接池dbcp和c3po的区别
    springboot数据库连接池使用策略
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/11251805.html
Copyright © 2020-2023  润新知