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>
using namespace std; int N;
int CN2 = 0;
int X[100005];
bool C(int x) { // 验证x作为中位数 x = X[j] - X[i] 是否太小
int cnt = 0;
for (int i = 0; i<N; ++i) {
cnt += N - (lower_bound(X + i, X + N, X[i] + x) - X); // 统计差值>=x的个数
}
return cnt > CN2 >> 1;
}
void solve() {
sort(X, X + N);
CN2 = N*(N - 1) >> 1;
int lb = 0, ub = 1000000001;
while (ub - lb > 1) {
int mid = (ub + lb) >> 1;
if (C(mid)) lb = mid; // 中位数过小,半闭半开区间[lb, ub)
else ub = mid;
}
printf("%d\n", lb);
}
int main()
{
while (scanf("%d", &N) == 1) {
for (int i = 0; i < N; ++i) scanf("%d", X + i);
solve();
}
return 0;
}

POJ 3685

题意:边为n的方阵中,aij=i^2+100000i+j^2-100000j+i*j,求矩阵的第k大数。

思路:需要注意数据规模,特别是1≤M≤N×N,需要64位变量来存

首先来分析下这个函数f(i,j)

可知f(i,j)按行递增(同列),而按列不单调(同行)。

C(x)表示矩阵中<x的元素有多少个。 所以可以一列一列来求有多少个比x小。然后二分求出正好有M−1个数比x小即可。

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll MAX = 1e15;
ll T;
ll N, M;
ll f(ll i, ll j) {
return i*i + 100000 * (i - j) + i*j + j*j;
}
bool C(ll x) { // 验证x是否过小。。。。这里写成int x调了好久= =
ll cnt = 0; // cnt 为<x的个数
for (int j = 1; j <= N; ++j) {
int lb = 0, ub = N + 1; // (lb, ub)
while (ub - lb > 1) {
int mid = (lb + ub) >> 1;
if (f(mid, j) < x) lb = mid; // 半闭半开区间[lb, ub)
else ub = mid;
}
cnt += lb;
}
return cnt < M;
}
void solve() {
ll lb = f(0, N), ub = f(N, 0) + 1;
while (ub - lb > 1) {
ll mid = (ub + lb) >> 1;
if (C(mid)) lb = mid; // 半闭半开区间[lb, ub)
else ub = mid;
}
cout << lb << endl;
}
int main() {
cin >> T;
while (T--) {
cin >> N >> M;
solve();
}
return 0;
}

POJ 3579 3685(二分-查找第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 2579 中位数问题 查找第K大的值

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

  4. 查找第K大的值

    这种题一般是给定N个数,然后N个数之间通过某种计算得到了新的数列,求这新的数列的第K大的值 POJ3579 题意: 用$N$个数的序列$x[i]$,生成一个新序列$b$. 新的序列定义为:对于任意的$ ...

  5. 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 ...

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

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

  7. hihoCoder 1133 二分·二分查找之k小数(TOP K算法)

    #1133 : 二分·二分查找之k小数 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回里我们知道Nettle在玩<艦これ>,Nettle的镇守府有很 ...

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

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

  9. hiho week 37 P1 : 二分·二分查找之k小数

    P1 : 二分·二分查找之k小数 Time Limit:10000ms Case Time Limit:1000ms Memory Limit:256MB 描述 在上一回里我们知道Nettle在玩&l ...

随机推荐

  1. golang匿名结构体

    go语言定义结构体类型时可以仅指定字段类型而不指定字段名字.这种字段叫做匿名字段(anonymous field). Go语言有一个特性允许只声明一个成员对应的数据类型而不指名成员的名字:这类成员就 ...

  2. for、foreach和Iterator区别及ConcurrentModificationException异常

    (问:1.for.foreach和Iterator遍历有什么区别    2.遍历删除ConcurrentModificationException异常.) 1.在形式上 for的形式是 for(int ...

  3. ubuntu上zip格式解压乱码解决

    在windows上压缩的文件,是以系统默认编码中文来压缩文件.由于zip文件中没有声明其编码,所以linux上的unzip一般以默认编码解压,中文文件名会出现乱码. 虽然2005年就有人把这报告为bu ...

  4. Python官方操作Excel文档

    xlwt 1.3.0 Downloads ↓ Library to create spreadsheet files compatible with MS Excel 97/2000/XP/2003 ...

  5. POJ3694 Network【连通分量+LCA】

    题意: 一个无向图可以有重边,下面q个操作,每次在两个点间连接一条有向边,每次连接后整个无向图还剩下多少桥(注意是要考虑之前连了的边,每次回答是在上一次的基础之上). 思路: 首先运行一次Tarjan ...

  6. Android学习笔记——Content Provider(一)

    Content Provider是Android系统四大组件之一: 官方的定义是:A Content Provider manages access to a central repository o ...

  7. MHA-Failover可能遇到的坑

    一.主从数据一致性 1.1.如何保证主从数据一致性 参考叶师傅文章:FAQ系列 | 如何保证主从复制数据一致性 在MySQL中,一次事务提交后,需要写undo.写redo.写binlog,写数据文件等 ...

  8. break case

    #include<stdio.h> main() { ; switch (g){ : : printf("haha"); break; : printf("h ...

  9. ViewPager制作APP引导页+若干动画效果

    ViewPager使用FragmentStatePagerAdapter做Adapter,引导页使用多Fragment形式. 见http://www.cnblogs.com/bmbh/p/567276 ...

  10. Android数据存储五种方式

    1 使用SharedPreferences存储数据:常用于做本地缓存 2 文件存储数据:(1)data/data/<package name>/files目录内   (2)SDCard内 ...