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,再套一个二分。

/*********************************************************
*            ------------------                          *
*   author AbyssalFish                                   *
**********************************************************/
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<cmath>
#include<numeric>
using namespace std;

typedef long long ll;
ll n, m;

const int d = 1e5;

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

int upp_b(ll j, ll x)
{
    if(f(j,1) > x) return 0;
    int lb = 1, ub = n, md;
    while(lb < ub ){
        md = (lb+ub+1)>>1;
        //f(j,md)>x? ub = md+1:lb = md+1;
        f(j,md)<=x? lb = md:ub = md-1;
    }
    return lb;
}

ll solve()
{
    if(m == 1) {
        ll ans = (3*n+d)*n;
        for(ll j = 1; j <= n; j++){
            ans = min(ans, (1+d+j)+(j-d)*j);
        }
        return ans;
    }
    if(m == n*n){
        ll ans = -(3*n+d)*n;
        for(ll j = 1; j <= n; j++){
            ans = max(ans, (n+d+j)*n-d*j+j*j);
        }
        return ans;
    }
    ll lb = -(3*n+d)*n, ub = -lb, md;
    while(lb < ub){
        md = (lb+ub)>>1;
        ll upb = 0;
        for(ll j = 1; j <= n; j++){
            upb += upp_b(j,md);
        }
        upb >= m?ub = md:lb = md+1;
    }
    return lb;
}

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    int T; scanf("%d",&T);
    while(T--){
        scanf("%I64d%I64d",&n,&m);
        printf("%I64d\n", solve());
    }
    return 0;
}
时间: 2024-08-02 19:18:38

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 二分

题目大意:有一个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 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 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

poj 3318 Matrix Multiplication

http://poj.org/problem?id=3318 矩阵A*矩阵B是否等于矩阵C 1 #include <cstdio> 2 #include <cstring> 3 #include <time.h> 4 #include <algorithm> 5 #define maxn 1010 6 using namespace std; 7 8 int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn],d[maxn];

POJ - 2155 Matrix (二维树状数组 + 区间改动 + 单点求值 或者 二维线段树 + 区间更新 + 单点求值)

POJ - 2155 Matrix Time Limit: 3000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Submit Status 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. Initially we ha

矩阵十点【两】 poj 1575 Tr A poj 3233 Matrix Power Series

poj 1575  Tr A 主题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1575 题目大意:A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. 数据的第一行是一个T,表示有T组数据. 每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据.接下来有n行,每行有n个数据,每一个数据的范围是[0,9].表示方阵A的内容. 一个矩阵高速幂的裸题. 题解: #

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 +