Time Limit: 6000MS Memory Limit: 65536K
Total Submissions: 4545 Accepted: 1143
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
Total Submissions: 4545 Accepted: 1143
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
这题坑死我了,之前一直在纠结是用lower_bound还是用upper_bound,WA了好多次,然后就是不敢不用long long了,貌似int型转换成long long会出问题。。
/*AC*/
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
ll N, M;
inline ll f(ll i, ll j){
return i*i + 100000*i + j*j - 100000*j + i*j;
}
ll binsearch(ll j, ll val){ //使用lower_bound查找第一个大于等于val的元素的下标,进而确定小于val元素的个数
ll lb = 0, ub = N+1;
while(ub - lb > 1){ //lower_bound使用左开右闭区间
ll mid = (lb+ub)>>1;
if(f(mid, j) >= val) ub = mid;
else lb = mid;
}
return ub-1; //返回小于val的元素个数
}
ll number(ll val){
ll cnt=0;
for(ll j=1; j<=N; j++){
cnt += binsearch(j, val);
}
return cnt;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%lld %lld", &N, &M);
ll lb = -5e9, ub = 2e10;
while(ub - lb > 1){ //仍然使用lower_bound
ll mid = (lb+ub)>>1;
if(number(mid) >= M) ub = mid;
else lb = mid;
}
printf("%lld\n", ub-1);
}
return 0;
}