传送门

https://www.luogu.org/problemnew/show/P4479

题目描述

在平面直角坐标系上,有 n 个不同的点。任意两个不同的点确定了一条直线。请求出所有斜率存在的直线按斜率从大到小排序后,第 k 条直线的斜率为多少。
为了避免精度误差,请输出斜率向下取整后的结果。(例如: ⌊1.5⌋ = 1 , ⌊−1.5⌋ = −2 )

分析

一开始打了一个暴力,10分后来改着改着成了30分,浮点误差。
正解其实很简单,我们首先逆向思考一下,如果我们假设已经有了斜率k。
如果两个点之间需要斜率大于k,并且假设我们已经排好了关于x横坐标的序(递增),那么一定会有一个\(\frac{y_j-y_i}{x_j-x_i}>k\)
那么进一步拆开式子最终得到\(y_j-kx_j>y_j-kx_j\),那么就变成了一个二维偏序,那么离散化+二分k+树状数组求解二维偏序就可以了。

ac代码

#include <bits/stdc++.h>
#define ll long long
#define db double
#define ms(a, b) memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
using namespace std;
template <typename T>
inline void read(T &x) {
    x = 0; T fl = 1;
    char ch = 0;
    while (ch < '0' || ch > '9') {
        if (ch == '-') fl = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    x *= fl;
}
#define N 100005
struct data {
    ll x, y, id, val;
    bool operator <(const data &rhs) const {
        return val == rhs.val ? x < rhs.x : val < rhs.val;
    }
}a[N];
struct BIT {
    #define lowbit(x) (x&-x)
    ll tr[N];
    int n;
    void init(int nn) {
        ms(tr, 0);
        n = nn;
    }
    void add(int x, int val) {
        for (; x <= n; x += lowbit(x)) tr[x] += val;
    }
    ll query(int x) {
        ll res = 0;
        for (; x; x -= lowbit(x)) res += tr[x];
        return res;
    }
}tr;
int n;
int disc_x[N];
ll k;
bool check(int x) {
    for (int i = 1; i <= n; i ++) {
        a[i].val = a[i].y - 1ll * x * a[i].x;
    }
    sort(a + 1, a + 1 + n);
    tr.init(n);
    ll ans = 0;
    for (int i = 1; i <= n; i ++) {
        ans += tr.query(a[i].id - 1);
        tr.add(a[i].id, 1);
    }
    return ans >= k;
}
int main() {
    read(n); read(k);
    for (int i = 1; i <= n; i ++) {
        read(a[i].x); read(a[i].y);
        disc_x[i] = a[i].x;
    }
    sort(disc_x + 1, disc_x + 1 + n);
    int disc_tot = unique(disc_x + 1, disc_x + 1 + n) - disc_x - 1;
    for (int i = 1; i <= n; i ++) {
        a[i].id = lower_bound(disc_x + 1, disc_x + 1 + disc_tot, a[i].x) - disc_x;
    }
    int l = -inf, r = inf, ans;
    while (l <= r) {
        int mid = (l + r) >> 1;
        if (check(mid)) l = mid + 1, ans = mid;
        else r = mid - 1;
    }
    printf("%d\n", ans);
    return 0;
}

[luogu4479][BJWC2018]第k大斜率【二维偏序+二分+离散化+树状数组】的更多相关文章

  1. 【二维偏序】【树状数组】【权值分块】【分块】poj2352 Stars

    经典问题:二维偏序.给定平面中的n个点,求每个点左下方的点的个数. 因为 所有点已经以y为第一关键字,x为第二关键字排好序,所以我们按读入顺序处理,仅仅需要计算x坐标小于<=某个点的点有多少个就 ...

  2. 【poj1901-求区间第k大值(带修改)】树状数组套主席树

    901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 7025  Solved: 2925[Sub ...

  3. Luogu P4479 [BJWC2018]第k大斜率

    一道清真简单的好写的题 Luogu P4479 题意 求点集两两连出的直线中斜率第$ k$大的直线 $ Solution$ 二分答案,设$x_j \geq x_i$ 若点$ (x_i,y_i)$和点$ ...

  4. 牛客网 牛客练习赛4 A.Laptop-二维偏序+离散化+树状数组

    A.Laptop 链接:https://ac.nowcoder.com/acm/contest/16/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其 ...

  5. [The Preliminary Contest for ICPC Asia Nanjing 2019] A-The beautiful values of the palace(二维偏序+思维)

    >传送门< 前言 这题比赛的时候觉得能做,硬是怼了一个半小时,最后还是放弃了.开始想到用二维前缀和,结果$n\leq 10^{6}$时间和空间上都爆了,没有办法.赛后看题解用树状数组,一看 ...

  6. 树状数组+二分答案查询第k大的数 (团体程序设计天梯赛 L3-002. 堆栈)

    前提是数的范围较小 1 数据范围:O(n) 2 查第k大的数i:log(n)(树状数组查询小于等于i的数目)*log(n)(二分找到i) 3 添加:log(n) (树状数组) 4 删除:log(n) ...

  7. 树状数组+二维前缀和(A.The beautiful values of the palace)--The Preliminary Contest for ICPC Asia Nanjing 2019

    题意: 给你螺旋型的矩阵,告诉你那几个点有值,问你某一个矩阵区间的和是多少. 思路: 以后记住:二维前缀和sort+树状数组就行了!!!. #define IOS ios_base::sync_wit ...

  8. 洛谷1527(bzoj2738)矩阵乘法——二维树状数组+整体二分

    题目:https://www.luogu.org/problemnew/show/P1527 不难想到(?)可以用二维树状数组.但维护什么?怎么查询是难点. 因为求第k小,可以考虑记权值树状数组,把比 ...

  9. 【转载】【树状数组区间第K大/小】

    原帖:http://www.cnblogs.com/zgmf_x20a/archive/2008/11/15/1334109.html 回顾树状数组的定义,注意到有如下两条性质: 一,c[ans]=s ...

随机推荐

  1. noode inquirer

    一. 由于交互的问题种类不同,inquirer为每个问题提供很多参数: type:表示提问的类型,包括:input, confirm, list, rawlist, expand, checkbox, ...

  2. freemarker数值格式化

    语法:number?string(exp) 说明:根据给定的格式化表达式将数值格式化为字符串. 参数:格式化字符串,"0"表示固定占位(至少有这个位数,不足位数用0代替),&quo ...

  3. CentOS 6.4 源码安装MySQL 5.6

    1.安装前准备工作 1.1 必备的包 gcc/g++ :MySQL 5.6开始,需要使用g++进行编译.cmake :MySQL 5.5开始,使用cmake进行工程管理,cmake需要2.8以上版本. ...

  4. cmake : undefined reference to dlopen, dlclose, dlsym and dlerror

    链接出了问题 添加头文件 #include <dlfcn.h> 添加库 target_link_libraries(PROJECT_NAME ${CMAKE_DL_LIBS})

  5. Quartz框架学习(1)—核心层次结构

    Quartz框架学习 Quartz(任务调度)框架的核心组件: job:任务.即任务调度行为中所要调度的对象. trigger:触发器.是什么促使了一个任务的调度?当然是时间.这也算事件驱动类型程序. ...

  6. redis 的简单命令

    以下实例讲解了如何启动 redis 客户端: 启动 redis 客户端,打开终端并输入命令 redis-cli.该命令会连接本地的 redis 服务. $redis-cli redis > re ...

  7. Netty派生缓冲区

    参考https://blog.csdn.net/wangjinnan16/article/details/77972113 派生缓冲区 派生缓冲区,也就是创建一个已经存在的缓冲区的视图,可以调用dup ...

  8. uwsgi加nginx部署django restframework前后端分离项目

    一.uwsgi和nginx简介 1.uwsgi(摘抄于百度百科): uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中HttpUwsgiModule的作用是与 ...

  9. python标准异常

    什么是异常? 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行.一般情况下,在Python无法正常处理程序时就会发生一个异常.异常是Python对象,表示一个错误.当Python脚 ...

  10. ERP系统的问题

    1.业务统计报表导出超时 2.库存统计相关接口查询容易导致慢查询,而且慢查询出现在主库上