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<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
ll N, M;

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

bool judge(ll mid) {
    ll cnt = 0;
    for(int j = 1; j <= N; j++) {
        int l = 1, r = N;
        while(l <= r) {
            int Mid = (l + r) / 2;
            if( Count(Mid,j) <= mid)
                l = Mid + 1;
            else
                r = Mid - 1;
        }
        cnt += l - 1;
    }
    return cnt < M;
}

ll solve() {
    ll l = -((ll)N * N * 3 + 100000 * N) , r = (ll)N * N * 3 + 100000 * N;

    while(l <= r) {
        ll mid = (l + r) / 2;
        if(judge(mid))
            l = mid + 1;
        else
            r = mid - 1;
    }
    return l;
}

int main(){
    int test;
    scanf("%d", &test);
    while(test--) {
        scanf("%lld%lld", &N, &M);
        printf("%lld\n",solve());
    }
    return 0;
}
时间: 2024-08-02 21:08:22

POJ - 3685 Matrix 二分的相关文章

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(取值范围:从0到n)是单调增加的,所以这里我们可以二分一个答案,然后一列一列的找小于(等于)它的个数,这样加起来我们就能知道我们枚举的这个答案是第几小了. 需要注意的是,第一个最外层的二分有点不同,因为我们二分的答案可能不存在

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,再套一个二分. /*****************************************************

POJ 3233 - Matrix Power Series ( 矩阵快速幂 + 二分)

POJ 3233 - Matrix Power Series ( 矩阵快速幂 + 二分) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; #define MAX_SIZE 30 #define CLR( a, b ) memset( a, b, sizeof(a) ) int MOD = 0; int n, k; st

Poj 3233 Matrix Power Series(矩阵二分快速幂)

题目链接:http://poj.org/problem?id=3233 解题报告:输入一个边长为n的矩阵A,然后输入一个k,要你求A + A^2 + A^3 + A^4 + A^5.......A^k,然后结果的每个元素A[i][j] % m.(n <= 30,k < 10^9,m < 10^4) 要用到矩阵快速幂,但我认为最重要的其实还是相加的那个过程,因为k的范围是10^9,一个一个加肯定是不行的,我想了一个办法就是我以k = 8为例说明: ans = A + A^2 + A^3 +

POJ 3579 3685(二分-查找第k大的值)

POJ 3579 题意 双重二分搜索:对列数X计算∣Xi – Xj∣组成新数列的中位数 思路 对X排序后,与X_i的差大于mid(也就是某个数大于X_i + mid)的那些数的个数如果小于N / 2的话,说明mid太大了.以此为条件进行第一重二分搜索,第二重二分搜索是对X的搜索,直接用lower_bound实现. #include <iostream> #include <algorithm> #include <cstdio> #include <cmath&g

poj 3233 Matrix Power Series(等比矩阵求和)

http://poj.org/problem?id=3233 ps转: 用二分方法求等比数列前n项和:即 原理: (1)若n==0 (2)若n%2==0     (3)若n%2==1 代码如下: LL sum(LL p,LL n) { if(n==0) return 1; if(n&1) return (1+pow(p,(n>>1)+1))*sum(p,n>>1); else return (1+pow(p,(n>>1)+1))*sum(p,(n-1)>&

POJ 2155 Matrix (二维线段树)

http://poj.org/problem?id=2155 Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 18143   Accepted: 6813 Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. I

POJ 3318 Matrix Multiplication(随机化算法)

给你三个矩阵A,B,C.让你判断A*B是否等于C. 随机一组数据,然后判断乘以A,B之后是否与乘C之后相等. 很扯淡的啊,感觉这种算法不严谨啊... Matrix Multiplication Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16255   Accepted: 3515 Description You are given three n × n matrices A, B and C. Does the e