中间数(二分)+单调队列

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行,每行一个整数ai1<=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)的,所以复杂度有了保证。

原文地址:https://www.cnblogs.com/fengzhiyuan/p/7942278.html