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();
    }
}