中间数(二分)+单调队列
1、中间数
(mid.cpp/c/pas)
【问题描述】:
有N个整数a1-aN,任意两个整数做绝对值差|ai-aj|(1<=i<j<=N)可以得到N*(N-1)/2个绝对值差,令M=N*(N-1)/2,保证M一定是个偶数,求第M/2小的数
【输入格式】:
输入文件名为mid.in。
第一行,一个整数N
接下来N行,每行一个整数ai(1<=ai<=1000,000,000)
【输出格式】:
输出文件名为mid.out。
一行,第M/2小的整数
【输入输出样例】:
mid.in |
mid.out |
4 1 10 2 3 |
2 |
【输入输出样例说明】
绝对值差分别是|1-10|=9,|1-2|=1,|1-3|=2,|10-2|=8,|10-3|=7,|2-3|=1
M=6,所以第M/2小的数是2
【数据说明】
30%1<=N<=1000
100%1<=N<=200000
题解:开始的时候想不到如何去求解,最后还是yzh大神solve了。这道题不错的,绝对值找中间数,
我不知道这个中间数是干什么用的,感觉完全可以给一个k来寻找第k大,或者第k小的解。题目是关
于绝对值的,可以转化一下,排个序,这样讲问题转换为:
我们设a[i+1]-a[i]=b[i],就是在一个集合中,集合元素为∑bi-j,问中间数,可以因为其值范围为1000000000,
随意想到了log 10^9*n这样的复杂度,二分一个x,如何知道比x小的有多少个,用一个单调队列,
比如1扩展到了z,那么2至少可以扩展到z,这样,来解决,以每个左端点为起点的答案数位r-l+1个,
这样是O(n)的,所以复杂度有了保证。