题意:给定长度为 的数组 ,其中 可正可负, 必为正。
定义函数 。
再给定两个整数 ,你需要求出一对 ,使得 在所有 中是第 小的,在所有 中是第 小的。
在本题中,我们称一个数 在序列
中是第 小的,当且仅当在 中有且仅有 个数 满足 ,且有且仅有 个数 满足 ,同时 。
如果不存在这样的 ,请输出
0 0
。如果有多组这样的 ,输出任意一组即可。
多组数据,,时限 。
考虑两点
连线斜率公式
。
对于 ,构造两点
,其中,前者称为蓝点,后者称为红点。(蓝点在左红点在右)
则某一蓝点和红点的连线斜率即为对应的 函数。
(利用分数规划也可得到类似结果)
现在问题转化成了 : 给出若干红点蓝点,红蓝点之间两两连线,求直线 ,使得其在蓝点 连出的线中斜率第 小,在红点 连出的线中斜率第 小。
考虑对于给定的点对
怎么计算排名。不难发现,对于蓝点 ,在该直线下方的红点点连线斜率小,上方大,故只需统计上下点数即可。对于红点
类似。
也就是说,我们找到的直线
需要满足其上方有 个蓝点,下方有
个红点。
令 ,则统一为下方点数。
仅仅凭借这两个信息,不便于直接得到所求直线。
不妨设该直线斜率为 ,此时容易(按照 )找出第 小的蓝点,即确定该直线。
记 表示在斜率为 的情况下,从第
小蓝点出发的直线下方包含的红点数目。
当 从 增长到 ,各个 也从 增长到 。化化式子不难证明 是单调增加的。
则可以二分 ,然后求 以判定(或者直接求出当前第 小的红点,看看是不是在直线下方)。
使用 nth_element
,复杂度可以做到 .
由于题目中对“第k大”的宽松定义,必定有解。