二分中间值x,x和大于等于x的值的数量cnt具有单调性,随着x增大,满足cntx <cntmid:111000。
中间值是满足条件最右边的一个。(所以是≤)
统计cnt。因为是取了绝对值,和Xi和Xj选取顺序没有关系,如果把X序列排序以后,枚举小的Xi,那么X[j] - X[i] ≥ x
找到满足条件最小的Xjmin,后面的都满足条件,Xi增大,Xjmin也是单调的,尺取就好。
/********************************************************* * ------------------ * * author AbyssalFish * **********************************************************/ #include<cstdio> #include<iostream> #include<string> #include<cstring> #include<queue> #include<vector> #include<stack> #include<vector> #include<map> #include<set> #include<algorithm> #include<cmath> #include<numeric> using namespace std; const int MAX_N = 1e5; int N; int X[MAX_N]; long long r_med; bool P(int x) //x>0 { long long cnt = 0; for(int i = 0, j = 1; i < N-1; i++){ while(j < N && X[i]+x > X[j]) j++; //if(i>=j) j++; cnt += N-j; } return cnt >= r_med; } //#define LOCAL int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif while(~scanf("%d",&N)){ for(int i = 0; i < N; i++) scanf("%d",X+i); sort(X,X+N); long long tot = ((N*(N-1LL))>>1); r_med = tot-((tot-1)>>1); int lb = 0, ub = X[N-1]-X[0], md; while(lb < ub){ md = (lb+ub+1)>>1; P(md) ? lb = md : ub = md-1; } printf("%d ",lb); } return 0; }