Loading

POJ-3685 Matrix

Matrix

给出一个\(n * n\)的表格,每个\(A_{ij}\)上有一个数字,其值为\(f(i, j) = i * i + 100000 * i + j * j - 100000 * j + i * j\),问第m小的值是多少

二分套二分

根据函数\(f(i, j)\),我们可以看到,在同一列或同一行中,表格中的值都是一个单调递增或单调递减的

因此我们可以通过\(O(nlogn)\)的时间复杂度,计算出表格中比任意数x小的有多少个数

以上的发现,给judge提供了一个可能,因此我们只要二分答案即可:第m小,代表着表格中小于等于ans的数字有m个,这是一个单调01分布

因此在主函数中通过枚举答案来的得到

二分查询答案,judge函数中也是一个二分询问,所以是二分套二分

时间复杂度:\(O(nlog^2n)\)

#include <cstdio>
using namespace std;
typedef long long ll;
ll n, m;

ll f(ll i, ll j)
{
    return i * i + 100000 * i + j * j - 100000 * j + i * j;
}

ll query(ll x)
{
    ll ans = 0;
    for(ll i=1; i<=n; i++)
    {
        ll l = 1, r = n + 1;
        while(l < r)
        {
            ll mid = l + r >> 1;
            if(f(mid, i) <= x)
                l = mid + 1;
            else
                r = mid;
        }
        ans += l;
    }
    return ans - n;

}

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%lld%lld", &n, &m);
        ll l = -1e17, r = 1e17;
        while(l < r)
        {
            ll mid = l + (r - l) / 2;
            if(query(mid) < m)
                l = mid + 1;
            else
                r = mid;
        }
        printf("%lld\n", l);
    }
    return 0;
}
posted @ 2022-04-25 18:16  dgsvygd  阅读(24)  评论(0编辑  收藏  举报