Matrix
Time Limit: 6000MS | Memory Limit: 65536K | |
Total Submissions: 6235 | Accepted: 1789 |
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
这道题的极限让我有点懵逼,只是不断的测试测试出来的
其中lb = 0, ub = N + 1.ub的大小为N + 1,个人觉得就有点尴尬了
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const LL INF = 1e14; int n; LL N, M; LL cal(LL i, LL j) { return i * i + 100000 * i + j * j - 100000 * j + i * j; } bool C(LL m) { LL res = 0; for(int i = 1; i <= N; i ++) { int lb = 0, ub = N + 1; while(ub - lb > 1) { int mid = (ub + lb) >> 1; if(cal(mid, i) >= m) { ub = mid; } else { lb = mid; } } res += lb; } return res >= M; } int main() { while(~scanf("%d", &n)) { for(int i = 0; i < n; i ++) { scanf("%lld%lld", &N, &M); LL lb = -INF, ub = INF; while(ub - lb > 1) { LL mid = (ub + lb) >> 1; if(C(mid)) { ub = mid; } else { lb = mid; } } printf("%lld\n", lb); } } return 0; }