思路:
二分套二分。
矩阵在每一列上是严格递增的,可以利用这一点进行二分。
实现:
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 using namespace std; 5 typedef long long ll; 6 const ll INF = 0x3f3f3f3f3f3f3f3f; 7 ll n, m; 8 ll cal(ll i, ll j) 9 { 10 return i * i + i * 100000 + j * j - j * 100000 + i * j; 11 } 12 bool check(ll x) 13 { 14 ll sum = 0; 15 for (int i = 1; i <= n; i++) 16 { 17 int l = 1, r = n, ans = 0; 18 while (l <= r) 19 { 20 int m = l + r >> 1; 21 ll tmp = cal(m, i); 22 if (tmp <= x) { ans = m; l = m + 1; } 23 else r = m - 1; 24 } 25 sum += ans; 26 } 27 return sum >= m; 28 } 29 int main() 30 { 31 int T; 32 scanf("%d", &T); 33 while (T--) 34 { 35 scanf("%lld %lld", &n, &m); 36 ll l = INF, r = -INF, ans = -INF; 37 for (int i = 1; i <= n; i++) 38 { 39 l = min(l, cal(1, i)); 40 r = max(r, cal(n, i)); 41 } 42 while (l <= r) 43 { 44 ll m = l + r >> 1; 45 if (check(m)) { ans = m; r = m - 1; } 46 else l = m + 1; 47 } 48 printf("%lld\n", ans); 49 } 50 return 0; 51 }