POJ 3685 二分

题意

传送门 POJ 3685

查找第 k k 大值的问题。二分第 k k 大的值,考虑单调性,对矩阵元素对行 i i 求偏导

2 i + 100000 + j > 0 2i+100000+j>0

矩阵在列方向上随行数增加单调递增。每次搜索第 k k 大的值,遍历 N N 列,二分求小于搜索值的元素个数。

注意此处元素索引范围为 [ 1 , N ] [1, N]

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define min(a,b)    (((a) < (b)) ? (a) : (b))
#define max(a,b)    (((a) > (b)) ? (a) : (b))
#define abs(x)    ((x) < 0 ? -(x) : (x))
#define INF 0x3f3f3f3f
#define delta 0.85
#define eps 1e-5
#define PI 3.14159265358979323846
#define MAX_N 100005
using namespace std;
typedef long long LL;
LL N, M;

bool C(LL x){
	LL s = 0;
	for(LL j = 1; j <= N; j++){
		LL lb = 0, ub = N + 1;
		while(ub - lb > 1){
			LL i = (lb + ub) >> 1;
			if(i * i + 1e5 * i + j * j - 1e5 * j + i * j < x) lb = i;
			else ub = i;
		}
		s += ub - 1;
	}
	return s < M;
}

int main(){
	int t;
	scanf("%d", &t);
	while(t--){
		scanf("%lld%lld", &N, &M);
		LL lb = -25e8, ub = 1e10;
		while(ub - lb > 1){
			LL mid = (lb + ub) >> 1;
			if(C(mid)) lb = mid;
			else ub = mid;
		}
		printf("%lld\n", lb);
	}
	return 0;
}
发布了91 篇原创文章 · 获赞 1 · 访问量 1604

猜你喜欢

转载自blog.csdn.net/neweryyy/article/details/105199544