题解 AT4867 【[ABC155D] Pairs】
题目
两次二分
首先对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】的更多相关文章
- 【题解】Palindrome pairs [Codeforces159D]
[题解]Palindrome pairs [Codeforces159D] 传送门:\(Palindrome\) \(pairs\) \([CF159D]\) [题目描述] 给定一个长度为 \(N\) ...
- ABC155D - Pairs
本题的模型是典型的求第k小问题,这个问题有2个不一样的点,一是任意选出2个数,不能是同一个,二是这个题有负数,那我们在原有的基础上就需要特判这两点,经典模型是2个数组相乘,此处是1个,那么一样可以枚举 ...
- LeetCode Maximum Length of Pair Chain
原题链接在这里:https://leetcode.com/problems/maximum-length-of-pair-chain/description/ 题目: You are given n ...
- 算法与数据结构基础 - 哈希表(Hash Table)
Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...
- 算法与数据结构基础 - 排序(Sort)
排序基础 排序方法分两大类,一类是比较排序,快速排序(Quick Sort).归并排序(Merge Sort).插入排序(Insertion Sort).选择排序(Selection Sort).希尔 ...
- 算法与数据结构基础 - 双指针(Two Pointers)
双指针基础 双指针(Two Pointers)是面对数组.链表结构的一种处理技巧.这里“指针”是泛指,不但包括通常意义上的指针,还包括索引.迭代器等可用于遍历的游标. 同方向指针 设定两个指针.从头往 ...
- Pairs Forming LCM (LCM+ 唯一分解定理)题解
Pairs Forming LCM Find the result of the following code: ; i <= n; i++ ) for( int j = i; j ...
- [LeetCode]Swap Nodes in Pairs题解
Swap Nodes in Pairs: Given a linked list, swap every two adjacent nodes and return its head. For exa ...
- [LeetCode 题解]:Swap Nodes in Pairs
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Given a li ...
随机推荐
- Go golang语言特性
一.垃圾回收 1.内存自动回收. 2.只需要创建,不需要释放 二.天然并发: 1.语言层支持并发,对比python,少了GIL锁. 2.goroute,轻量级线程. 3.基于CSP模型实现 三.cha ...
- 盘点一下Github上开源的编程面试/学习相关的仓库
转载自:JavaGuide 最近浏览 Github ,收藏了一些还算不错的 Java面试/学习相关的仓库,分享给大家,希望对你有帮助.我暂且按照目前的 Star 数量来排序. 本文由 SnailCli ...
- 刨根问底系列(3)——关于socket api的原子操作性和线程安全性的探究和实验测试(多线程同时send,write)
多个线程对同一socket同时进行send操作的结果 1. 概览 1.1 起因 自己写的项目里,为了保证连接不中断,我起一个线程专门发送心跳包保持连接,那这个线程在send发送数据时,可能会与主线程中 ...
- AJ学IOS 之微博项目实战(12)发送微博自定义工具条代理实现点击事件
AJ分享,必须精品 一:效果 二:封装好的工具条 NYComposeToolbar.h 带代理方法 #import <UIKit/UIKit.h> typedef enum { NYCom ...
- Linux安装PHP的Redis扩展(已安装Redis)
1.下载需要的php操作redis的扩展包 下载地址 http://pecl.php.net/package/redis 下载对应php版本,我的php版本为7.3,下载的是最新的版本5.0.2 ...
- python3 xlwt,csv学习
前言 对于抓取一些站点分析然后指纹识别的时候可能用到到它.所以学习下.这里就记录一些最基本的感觉有用的. xlwt 基本创建 demo: #coding=utf- import xlwt yunyin ...
- 【题解】POJ3041 Asteroids - 图论 - 二分图匹配
声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 POJ3041 Asteroids 题目描述 假如你现在正处在一个 \(N*N\ ...
- Django文档阅读-Day3
Django文档阅读-Day3 Writing your first Django app, part 3 Overview A view is a "type" of Web p ...
- Java IO基础--File常用操作(递归)
File中经常会使用递归方法打印属性结构.统计文件夹下文件个数.子文件夹个数以及文件大小,可以作为递归的应用练习. 递归的写法,百度一搜一大堆,这里我使用对javabean方式封装了一下: packa ...
- 负载均衡服务之HAProxy基础配置(四)
前文我们聊了haproxy的状态页配置,状态页中显示各参数的含义,以及基于cookie做会话保持的配置,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12776 ...