POJ 3685 Matrix 二分套二分

POJ 3685 Matrix 二分

题意

有一个N阶方阵,方正中第i行第j列的元素值为\(d_{i,j}=i^{2}+1e5*i+j^{2}-1e5*j+i*j\),我们需要找出这个方阵中第M小的元素值。

解题思路

分析这个公式,我们发现:当j固定的时候,这个公式关于i(取值范围:从0n)是单调增加的,所以这里我们可以二分一个答案,然后一列一列的找小于(等于)它的个数,这样加起来我们就能知道我们枚举的这个答案是第几小了。

需要注意的是,第一个最外层的二分有点不同,因为我们二分的答案可能不存在,但是也是符合第m小,这个情况还是需要注意的,这里需要参看关于二分的第四种形式。二分链接

代码实现

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<stack>
#include<queue>
#include<map>
typedef long long ll;
using namespace std;
const double esp=1e-6;
const int inf=0x3f3f3f3f;
const int MAXN=1E6+7;
ll n, m;
ll fun(ll i, ll j)
{
    return i*i+100000*i+j*j-100000*j+i*j;
}
void dis()
{
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            printf("%lld ", fun(i, j));
        }
        printf("\n");
    }
}
ll solve(ll value)
{
    ll sum=0;
    for(ll j=1; j<=n; j++)
    {
        ll left=0, right=n+1, ans=0;
        while(left < right)
        {
            ll mid=left+(right-left)/2;
            if(fun(mid, j) <= value)
                left=mid+1;
            else right=mid;
        }
        if(left!=0)
            sum+=left-1;
    }
    return sum;
}
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%lld%lld", &n, &m);
//      dis();
        ll lt=-1e12, rt=1e12, ans;
        while(lt+1 < rt) //这里的二分我们提前是不知道该向左侧还是右侧前进的。
        {
            ll mid = lt + (rt-lt)/2;
            ll tmp=solve(mid);
            if(tmp >= m)
            {
                ans=mid;
                rt=mid;
            }
            else lt=mid;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/alking1001/p/12257226.html

时间: 2024-12-11 10:32:39

POJ 3685 Matrix 二分套二分的相关文章

POJ 3685 二分套二分

Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i2 + 100000 × i + j2 - 100000 × j + i × j, you are to find the M-th smallest element in the matrix. Input The first line of input is the number of test

POJ-3579 Median---二分第k大(二分套二分)

题目链接: https://cn.vjudge.net/problem/POJ-3579 题目大意: 求的是一列数所有相互之间差值的序列的最中间的值是多少. 解题思路: 可以用二分套二分的方法求解第m大,和POJ-3685类似,这里的模板也差不多 枚举第m大x,判断小于等于x的数目是不是大于m,如果大于m说明x >= 第m大,调整区间r = mid - 1 不然l = mid + 1 此处是大于m而不是小于m是因为一个数可能出现多次,那么小于等于中间的数目可能就比m大 在计算小于等于x的数目的时

POJ - 3685 Matrix 二分

题目大意:有一个N * N的矩阵,其中Aij = i * i + i * 100000 - 100000 * j + j * j + i * j,问这个矩阵中,第M小的数是多少 解题思路:观察这个式子,可以发现j不变的情况下,随着i的增大,Aij也相应增大,由这个受到启发 二分枚举第M小的数,然后按列寻找,找到第一个大于这个数的位置,就可以知道该列中有多少个数是大于这个数的了 #include<cstdio> #include<cstring> #include<algori

POJ 3685 二分套二分(水题

题意:给出一个N*N的矩阵A,A[i][j]的值等于i2 + 100000 ×i + j2 - 100000 × j + i × j,求这个矩阵中第M小的数 代码: 1 #include <cstdio> 2 #include <iostream> 3 using namespace std; 4 long long N; 5 long long cal(long long i,long long j){ 6 return i*i+100000*i+j*j-100000*j+i*j

POJ 3233 Matrix Power Series 二分+矩阵乘法

链接:http://poj.org/problem?id=3233 题意:给一个N*N的矩阵(N<=30),求S = A + A^2 + A^3 + - + A^k(k<=10^9). 思路:非常明显直接用矩阵高速幂暴力求和的方法复杂度O(klogk).肯定会超时.我採用的是二分的方法, A + A^2 + A^3 + - + A^k=(1+A^(k/2)) *(A + A^2 + A^3 + - + A^(k/2)).这样就能够提出一个(1+A^(k/2)),假设k是奇数,单独处理A^k.

POJ 3233 Matrix Power Series --二分求矩阵等比数列和

题意:求S(k) = A+A^2+...+A^k. 解法:二分即可. if(k为奇)  S(k) = S(k-1)+A^k else        S(k) = S(k/2)*(I+A^(k/2)) 代码: #include <iostream> #include <cmath> #include <cstdio> #include <cstdlib> #define SMod m using namespace std; int n,m,k; struct

poj 3685 Matrix(二分搜索之查找第k大的值)

Description Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i2 + 100000 × i + j2 - 100000 × j + i × j, you are to find the M-th smallest element in the matrix. Input The first line of input is the nu

POJ - 3685 Matrix

二分kth,答案满足的条件为:m ≤ 小于等于x的值数cntx.x和cntx单调不减,随着x增大,条件成立可表示为:0001111. 本地打一个小型的表可以发现列编号j固定时候,目标函数f(i,j)似乎具有单调性. 变形,f(i,j) = (i+100000+j)*i + j2 - 100000,可以看出确实具有单调性. 于是得到如下算法: 二分x,统计cnt时候,枚举j,再套一个二分. /*****************************************************

poj3685 二分套二分

F - 二分二分 Crawling in process... Crawling failed Time Limit:6000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Status Description Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i2