这种题一般是给定N个数,然后N个数之间通过某种计算得到了新的数列,求这新的数列的第K大的值


POJ3579

题意:

用$N$个数的序列$x[i]$,生成一个新序列$b$。

新的序列定义为:对于任意的$ i$,$j$且 $i != j $有$b[] = abs(x[i] - x[j])$

问新序列的中位数是什么,如果新序列的长度为偶数那么我们定义中位数为排序后第len/2位置的那个数

解法:

相当于问新序列中的第K大的数多少。

注意新数列不可能全都算出来。

二分答案,二分那个第K大的数的值。

$x[i]-x[j] \ge mid$

相当于

$x[i] \ge mid+x[j]$

然后我们在排序过的原数组中,对每个$a[i]$二分这个$mid$值,统计有多少个值小于它,统计累加所有的值,最后看是不是小于K

代码如下:

 int N;
int a[MAXN];
LL M; bool C(int t) {
LL cnt = ;
for (int i = ; i < N; i++) {
cnt += N - (lower_bound(a + i + , a + N, a[i] + t) - a);
}
return cnt <= M / ;
} void solve() {
sort(a, a + N);
M = N * (N - ) / ;
int ub = a[N - ] + , lb = ;
while (ub - lb > ) {
int mid = (ub + lb) >> ;
if (C(mid)) {
ub = mid;
} else {
lb = mid;
}
}
cout << lb << endl;
return;
} int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif // !ONLINE_JUDGE
while (~scanf("%d", &N)) {
for (int i = ; i < N; i++) {
scanf("%d", &a[i]);
}
solve();
}
return ;
}

POJ3685

题意:

有一个$ N*N$ 的矩阵$ A$ ,$A[i][j]=i^2+100000i+j^2-100000j+ij$

求所有矩阵元素中第$ K$ 大的值

解法:

求第$ K$ 大的值,二分答案

首先肯定是二分这个K值是多少,接下来就是验证的问题。

由于$ N*N$ 的值很大,所以我们必须找到它的单调性,那么有以下式子:

$A[i+1][j] = A[i][j] + (2*i + j + 1 + 100000)$(同一列递推式)

$A[i][j+1] = A[i][j] + (2*j + i + 1 - 100000)$ (同一行递推式)

可以发现:在列方向上,矩阵单调递增,而在行方向上上,当$ (2*j + i + 1)> 100000 $ 时,递增,反之递减。

那么我们在每个列方向上直接二分那个$ i$ 值的大小,判断的一句就是$ A[i][j]$ 与假想$ K$ 值的大小关系。

代码如下:

 LL N, M;

 LL cal(LL i, LL j) { return i * i +  * i + j * j -  * j + i * j; }

 bool C(LL x) {
LL sum = ;
for (int j = ; j <= N; j++) {
LL ub = N + , lb = ;
LL ans = ;
while (ub - lb > ) {
LL mid = (ub + lb) >> ;
if (cal(mid, j) <= x) {
ans = mid;
lb = mid;
} else {
ub = mid;
}
}
sum += ans;
}
return sum >= M;
} void solve() {
LL ub = LLINF, lb = -LLINF;
while (ub - lb > ) {
LL mid = (ub + lb) >> ;
if (C(mid)) {
ub = mid;
} else {
lb = mid;
}
}
cout << ub << endl;
return;
} int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif // !ONLINE_JUDGE
int T = READ();
while (T--) {
getchar();
scanf("%lld%lld", &N, &M);
solve();
}
return ;
}

查找第K大的值的更多相关文章

  1. POJ_3685_Matrix_(二分,查找第k大的值)

    描述 http://poj.org/problem?id=3685 一个n*n的矩阵,(i,j)的值为i*i+100000*i+j*j-100000*j+i*j,求第m小的值. Matrix Time ...

  2. POJ_3579_Median_(二分,查找第k大的值)

    描述 http://poj.org/problem?id=3579 给你一串数,共C(n,2)个差值(绝对值),求差值从大到小排序的中值,偶数向下取. Median Time Limit: 1000M ...

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

    POJ 3579 题意 双重二分搜索:对列数X计算∣Xi – Xj∣组成新数列的中位数 思路 对X排序后,与X_i的差大于mid(也就是某个数大于X_i + mid)的那些数的个数如果小于N / 2的 ...

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

    Description Given a N × N matrix A, whose element × i + j2 - × j + i × j, you are to find the M-th s ...

  5. poj 2579 中位数问题 查找第K大的值

    题意:对列数X计算∣Xi – Xj∣组成新数列的中位数. 思路:双重二分搜索 对x排序 如果某数大于 mid+xi 说明在mid后面,这些数的个数小于 n/2 的话说明这个中位数 mid 太大 反之太 ...

  6. poj 3579 Median (二分搜索之查找第k大的值)

    Description Given N numbers, X1, X2, ... , XN, let us calculate the difference of every pair of numb ...

  7. 利用划分树求解整数区间内第K大的值

    如何快速求出(在log2n的时间复杂度内)整数区间[x,y]中第k大的值(x<=k<=y)? 其实我刚开始想的是用快排来查找,但是其实这样是不行的,因为会破坏原序列,就算另外一个数组来存储 ...

  8. 基于快速排序思想partition查找第K大的数或者第K小的数。

    快速排序 下面是之前实现过的快速排序的代码. function quickSort(a,left,right){ if(left==right)return; let key=partition(a, ...

  9. poj_3662 最小化第k大的值

    题目大意 有N个节点以及连接的P个无向边,现在要通过这P条边从1号节点连接到N号节点.若无法连接成功,则返回-1:若能够连接成功,那么其中用到了L条边,这L条边中有K条边可以免费,L-K条边不能免费, ...

随机推荐

  1. 使用C++进行声明式编程

            声明式编程(英语:Declarative programming)是一种编程范型,与命令式编程相对立.它描述目目标性质,让计算机明白目标,而非流程.声明式编程不用告诉电脑问题领域,从而 ...

  2. cmd命令行窗口和文件目录资源管理器快速切换

    本文主要描述如何在指定目录下快速打开当前路径的命令行窗口和在命令行中快速打开指定目录的资源管理器两种快捷方法. 1.在指定目录下快速打开当前路径的命令行窗口 2.在命令行中快速打开当前目录的资源管理器 ...

  3. js解析json时报:Unexpected token s in JSON at position 0

    原因肯定是返回的json格式有问题 最有可能是后台在程序执行过程中,输出了某些调试信息等等,这些输出的字符串和json拼接成了新的字符串来解析,这时就会报错: 比如我在入口文件里var_dump了__ ...

  4. Shell常用命令之主机检测(ping)

    主机检测命令ping 向网络主机发送ICMP回传请求 常用选项 -A:洪水攻击选项,启用此功能能在短时间之内发送大量的ping包 -b:开启ping网桥模式,默认不允许ping网桥 -c:设置发送多少 ...

  5. 程序的健壮性Robustness

    所谓的程序健壮性是指处理异常的能力,在异常中能够独立处理异常,并且把正确的答案输出. 例如: 有一个程序能够下载一个文件到指定的路径,但是这个路径是不存在的,因此程序必须要处理这个情况. 例1:下面的 ...

  6. 一段关于用户登录 和乘法表的python代码

    用户登录代码(低配): name = 1password =11counter = 1while counter <3 : a = int(input ('name:')) #注意这里 inpu ...

  7. Unreal Engine 4 蓝图完全学习教程(一)—— 简要介绍

    首先启动UE4: 新建项目类型为游戏: 选择空项目Blank: 项目设置选项: 点击创建项目: 打开后的窗口称为:“关卡编辑器”,由多个面板组成.在UE中,设计3D场景的空间称为“关卡”. 简单介绍一 ...

  8. Solaris磁盘镜像恢复

    注:此文章笔者实验记录,欢迎大家指正 Solaris磁盘镜像恢复方法一: 系统启动,开机提示子镜像需要维护: 查看磁盘镜像信息 进入系统后,metastat -pc 和metadb #查看镜像状态与m ...

  9. FFmpeg被声明为已否决的解决方案

    参考雷神的最简单的打印Hello World的程序: #include <stdio.h> #include <string.h> extern "C" { ...

  10. 使用html及CSS实现在table中文字信息超过5个隐藏,鼠标移到时弹窗显示全部:

    使用html及CSS实现在table中文字信息超过5个隐藏,鼠标移到时弹窗显示全部: <!DOCTYPE html><html lang="en">< ...