POJ3685 Matrix【二分搜索】

Matrix
Time Limit: 6000MS Memory Limit: 65536K
Total Submissions: 11546 Accepted: 3633

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
Source

POJ Founder Monthly Contest – 2008.08.31, windy7926778

问题链接POJ3685 Matrix
问题简述:(略)
问题分析:二分搜索问题,需要2重二分搜索。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* POJ3685 Matrix */

#include <iostream>
#include <cstdio>

using namespace std;

typedef long long LL;

LL f(LL i, LL j)
{
    return i * i + 100000 * i + j * j - j * 100000 + i * j;
}

LL n, m;

LL judge(LL x)
{
    LL sum = 0;
    for(LL i = 1; i <= n; i++) {
        LL left = 0, right = n + 1, mid;
        while(right - left > 1) {
            mid = (left + right) / 2;
            if(f(mid, i) < x) left = mid;
            else right = mid;
        }
        sum += left;
    }
    return sum;
}

int main()
{
    int t;
    scanf("%d", &t);
    while(t--) {
        scanf("%lld%lld", &n, &m);

        LL left = -1e12, right = 1e12, mid;
        while(right - left > 1) {
            mid = (left + right) / 2;
            if(judge(mid) < m) left = mid;
            else right = mid;
        }

        printf("%lld\n", left);
    }

    return 0;
}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页