基爷的中位数
Time Limit: 20 Sec Memory Limit: 256 MB
题目连接
http://acm.uestc.edu.cn/#/contest/show/61
Description
给你N个数,X1,X2,…,XN, 基爷让我们计算任意两个数差的绝对值 ∣Xi−Xj∣ (1≤i<j≤N) 。 这样,我们可以得到 C2N 个数。
现在,基爷希望聪明的你能用一个简单的程序求出这 C2N 个数的中位数!
Input
输入有多组数据。
每组数据,第一行一个整数 N,第二行给出 N 个整数 X1,X2,…,XN ( |Xi|≤1,000,000,000; 3≤N≤100,000 )
Output
按要求输出中位数,每个数占一行。
Sample Input
4
1 3 2 4
3
1 10 2
Sample Output
1
8
HINT
当这 C2N 个数的个数为偶数 M 的时候,取第 ⌊M2⌋ 个最小的数作为中位数 ( 别问为什么,这就是基爷的中位数! )
题意
题解:
二分答案枚举中位数,然后再二分 a[i]-a[j]=二分的那个数的值在哪儿
nloglog的做法
nlog就要用two pointer去优化
代码:
//qscqesze #include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> #include <stack> typedef long long ll; using namespace std; //freopen("D.in","r",stdin); //freopen("D.out","w",stdout); #define sspeed ios_base::sync_with_stdio(0);cin.tie(0) #define maxn 200001 #define mod 10007 #define eps 1e-9 int Num; char CH[20]; //const int inf=0x7fffffff; //нчоч╢С const int inf=0x3f3f3f3f; /* inline void P(int x) { Num=0;if(!x){putchar('0');puts("");return;} while(x>0)CH[++Num]=x%10,x/=10; while(Num)putchar(CH[Num--]+48); puts(""); } */ inline ll read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void P(int x) { Num=0;if(!x){putchar('0');puts("");return;} while(x>0)CH[++Num]=x%10,x/=10; while(Num)putchar(CH[Num--]+48); puts(""); } //************************************************************************************** ll a[maxn],n; ll tmp; int main() { while(scanf("%lld",&n)!=EOF) { for(int i=0;i<n;i++) scanf("%lld",&a[i]); tmp=n*(n-1)/2; sort(a,a+n); ll l=0,r=722337203685477580; while(l+1<r) { ll mid=(l+r)>>1; ll ans=0; for(int i=0;i<n;i++) { ans+=a+n-lower_bound(a+i+1,a+n,a[i]+mid); } if(ans<=tmp/2) r=mid; else l=mid; } printf("%lld\n",l); } }