题目

两次二分

首先对ans进行二分,在\([-10^{18},10^{18}]\)之间

考虑怎么check

对于每个ans,枚举每个\(a_i\),二分查找有几个\(a_j\),使得\(a_i\times a_j<ans\)

对于每对合法的\((a_i,a_j)\),枚举到\(a_i\)和\(a_j\)的时候都被找了一遍,所以最后应该除以2来去重

因为不能出现\(a_i=a_j\),所以返回的时候要把\(i=j\)的情况去掉

两个数组a,b

将输入的数在a中按升序排序,在b中按降序排

在第二次二分时,当\(a_i<0\),用b数组二分(负负得正,所以此时绝对值更大的负时是“大”的,因为它与\(a_i\)的乘积更大),当\(a_i\geq 0\),用a数组,这样保证了可二分性

通过第一层二分,我们找到的其实是在n个\(a_i\)两两相乘得到的数中,比从小到大第k个数大的最小数,所以要输出\(ans-1\)

复杂度\(O(n\log n\log 10^{18})\)

code.

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#define R register
#define EN std::puts("")
#define LL long long
inline LL read(){
LL x=0,y=1;
char c=std::getchar();
while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
return y?x:-x;
}
//a:abs大的负数->abs小的负数->小正数->大正数
//b:大正数->小正数->abs小的负数->abs大的负数
int n,fir;//a[fir]是a数组中第一个非负数
LL k;
LL a[200006],b[200006];
inline int finda(int i,LL ans){
R int l=1,r=n,mid,ret=0;
while(l<=r){
mid=(l+r)>>1;
if(a[mid]*a[i]<ans) ret=mid,l=mid+1;
else r=mid-1;
}
return ret>=i?(ret-1):ret;//如果ret>=i,说明其中有一对是两个a[i]相乘得到,此时要减1
}
inline int findb(int i,LL ans){
R int l=1,r=n,mid,ret=0;
while(l<=r){
mid=(l+r)>>1;
if(b[mid]*a[i]<ans) ret=mid,l=mid+1;
else r=mid-1;
}
return (ret+i>n)?(ret-1):ret;//同理,但b是倒序
}
inline int check(LL ans){
LL nowk=0;
for(R int i=1;i<fir;i++)//负数
nowk+=findb(i,ans);
for(R int i=fir;i<=n;i++)//正数
nowk+=finda(i,ans);
nowk/=2;//去重
return nowk>=k;
}
inline int cmp(int x,int y){
return x<y;
}
int main(){
n=read();k=read();
for(R int i=1;i<=n;i++) a[i]=read();
std::sort(a+1,a+1+n,cmp);
fir=n+1;
for(R int i=1;i<=n;i++)
if(a[i]>=0){fir=i;break;}
for(R int i=1;i<=n;i++) b[n-i+1]=a[i];//存入b数组,对负数二分时使用
R LL l=-1e18,r=1e18,mid,ans;
while(l<=r){
mid=(l+r)/2;
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
std::printf("%lld",ans-1);
return 0;
}

题解 AT4867 【[ABC155D] Pairs】的更多相关文章

  1. 【题解】Palindrome pairs [Codeforces159D]

    [题解]Palindrome pairs [Codeforces159D] 传送门:\(Palindrome\) \(pairs\) \([CF159D]\) [题目描述] 给定一个长度为 \(N\) ...

  2. ABC155D - Pairs

    本题的模型是典型的求第k小问题,这个问题有2个不一样的点,一是任意选出2个数,不能是同一个,二是这个题有负数,那我们在原有的基础上就需要特判这两点,经典模型是2个数组相乘,此处是1个,那么一样可以枚举 ...

  3. LeetCode Maximum Length of Pair Chain

    原题链接在这里:https://leetcode.com/problems/maximum-length-of-pair-chain/description/ 题目: You are given n  ...

  4. 算法与数据结构基础 - 哈希表(Hash Table)

    Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...

  5. 算法与数据结构基础 - 排序(Sort)

    排序基础 排序方法分两大类,一类是比较排序,快速排序(Quick Sort).归并排序(Merge Sort).插入排序(Insertion Sort).选择排序(Selection Sort).希尔 ...

  6. 算法与数据结构基础 - 双指针(Two Pointers)

    双指针基础 双指针(Two Pointers)是面对数组.链表结构的一种处理技巧.这里“指针”是泛指,不但包括通常意义上的指针,还包括索引.迭代器等可用于遍历的游标. 同方向指针 设定两个指针.从头往 ...

  7. Pairs Forming LCM (LCM+ 唯一分解定理)题解

    Pairs Forming LCM Find the result of the following code: ; i <= n; i++ )        for( int j = i; j ...

  8. [LeetCode]Swap Nodes in Pairs题解

    Swap Nodes in Pairs: Given a linked list, swap every two adjacent nodes and return its head. For exa ...

  9. [LeetCode 题解]:Swap Nodes in Pairs

    前言   [LeetCode 题解]系列传送门:  http://www.cnblogs.com/double-win/category/573499.html   1.题目描述 Given a li ...

随机推荐

  1. hadoop(六)rsync远程同步|xsync集群分发(完全分布式准备三)|8

    前置环境准备:centos7克隆ip|机器名|映射关系|别名配置(hadoop完全分布式准备一)scp命令copy文件和配置(hadoop完全分布式准备二) rsync远程同步工具 优点 rsync主 ...

  2. 使用 Python 查看局域网内存活主机

    1 安装 (如果误用了 pip insatll nmap的话,要先 pip uninstall nmap) pip install python-nmap Nmap 是一款用于网络发现和安全审计的网络 ...

  3. PostgreSQL中RECURSIVE递归查询使用总结

    RECURSIVE 前言 CTE or WITH 在WITH中使用数据修改语句 WITH使用注意事项 RECURSIVE 递归查询的过程 拆解下执行的过程 1.执行非递归部分 2.执行递归部分,如果是 ...

  4. curl 交叉编译 支持http2和openssl

    touch run.sh chmod 755 run.sh mkdir build cd build ../run.sh run.sh #!/bin/bash #cd /build ../config ...

  5. win7下delphi中的help文档问题

    一,要安装WinHlp32.exe 文件 二, 三,在安装目录下:

  6. 2.hover的使用

    1. 自身的hover div :hover{  :hover前要有空格  } 2.hover指向子元素 father:hover .childer {   :hover前不能有空格   } 3.ho ...

  7. vue原生表格怎样实现动态列及表格数据下载

    最近项目经常用到带有合并效果以及动态列的表格,而翻阅iview和element-ui官网没有找到合适的(也有可能自己的水平有限,不会改写),所以只好自己用原生表格写了一个,具体效果如下: 这个表格右侧 ...

  8. python 基础篇 错误和异常处理

    语法错误 所谓语法错误,也就是你写的代码不符合编程规范,无法被识别与执行,比如下面这个例子: if name is not None print(name) If 语句漏掉了冒号,不符合 Python ...

  9. TensorFlow keras卷积神经网络 添加L2正则化

    model = keras.models.Sequential([ #卷积层1 keras.layers.Conv2D(32,kernel_size=5,strides=1,padding=" ...

  10. awk,seq,xarg实例使用

    基于https://www.cnblogs.com/wangyuebo/p/5836933.html的详细补充讲解 [root@localhost awk]# seq 10|xargs -n 2 &g ...