POJ 3685: Matrix
概要
N次正方行列があって,その(i,j)-成分はi^2+100000*i+j^2-100000*j+i*jで与えられる.
M番目に小さい要素の値はいくつか.
解法
解について二分探索.列を固定してしまえば,値は行について単調増加であることが式からわかる.
2次方程式を解けばO(1)で計算できるのだろうけど,ここでも二分探索を使った.
#include <cstdio> #include <algorithm> typedef long long ll; const ll MAX_N = 50010; ll N, M; ll func(ll i, ll j){ return i * i + 100000 * i + j * j - 100000 * j + i * j; } bool C(ll x){ ll cnt = 0; for(int j = 1; j <= N; ++j){ ll lb = 0, ub = N + 1; while(ub - lb > 1){ ll mid = (lb + ub) / 2; if(func(mid, j) < x){ lb = mid; } else{ ub = mid; } } cnt += lb; } // printf(">>%lld\n", cnt); return cnt < M; } main(){ int T; scanf("%d", &T); for(;T>0;--T){ scanf("%lld%lld", &N, &M); ll ub = MAX_N * MAX_N * 3 + MAX_N * 100000 * 2; ll lb = -ub; while(ub - lb > 1){ ll mid = (lb + ub) / 2; // printf("(%lld)\n", mid); if(C(mid)){ lb = mid; } else{ ub = mid; } } printf("%lld\n", lb); } return 0; }