Matrix POJ3685
投稿日: 更新日:
問題:http://poj.org/problem?id=3685
問題
の行列があります。行目列目をとしたとき、その値はに等しいです。整数が与えられるので、番目に小さい値を出力してください。
解法
となる値が個以上か、で二分探索します。
の値はを固定した際、について単調増加です。よって、各に対し二分探索での個数を数えて行けば良いです。
実装
#include <iostream>
using namespace std;
long long calc(long long i, long long j){
return i*i + 100000*i + j*j - 100000*j + i*j;
}
void solve(){
int n;
long long m;
cin >> n >> m;
long long ok = 1e18, ng = -1e18;
while(ok-ng > 1){
long long v = (ok+ng)/2;
long long count = 0;
for(int j = 1;j <= n; ++j){
int ok = 0, ng = n+1;
while(ng - ok > 1){
int mid = (ok+ng)/2;
if(calc(mid, j) <= v){
ok = mid;
}else{
ng = mid;
}
}
count += ok;
}
if(count >= m){
ok = v;
}else{
ng = v;
}
}
cout << ok << endl;
}
int main(){
int t;
cin >> t;
while(t--){
solve();
}
}