欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

POJ 3685 Matrix 二分嵌套

程序员文章站 2024-03-17 15:09:10
...

题意:给一个数n,在n*n的矩阵中第i行第j列数等于i² + 100000 × i + j² - 100000 × j + i × j,求这些数中最小的第m个数
思路:内层对j二分求比x小的sum个数,外层对每个数x二分,求sum大于等于m的第一个数,复杂度O(log(nlogn))

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 50005;
ll n, m, T;
ll cal(ll i, ll j)
{
	return i*i+1e5*i+j*j-1e5*j+i*j;
}
ll check(ll x)
{
	ll sum = 0, l, r, ans = 0;
	for (int i = 1; i <= n; i++) {
		l = 1, r = n;
		while (l <= r) {
			ll mid = (l + r) >> 1;
			if (cal(mid, i) <= x) {
				ans = mid;
				l = mid + 1;
			} else {
				r = mid - 1;
			}
		}
		sum += ans;
	}
	return sum;
}
int main()
{
	ll l, r, ans, mid;
	scanf("%lld", &T);
	for (int i = 0; i < T; i++) {
		scanf("%lld%lld", &n, &m);
		l = -1e10, r = 1e10;
		while (l <= r) {
			mid = (l+r) >> 1;
			if (check(mid) >= m) {
				r = mid - 1;
				ans = mid;
			} else {
				l = mid + 1;
			}
		}
		printf("%lld\n", ans);
	}
	return 0;
}
相关标签: ACM