Description
Solution
这是一道很经典的题目,模型也很经典。
首先,肯定是二分答案出mid。
假设我们现在要求前k大,
要找出所有的点对满足sum[r]−sum[l]r−l≥mid,那么把不等式转化一下sum[r]−mid∗r≥sum[l]−mid∗l,要满足至少k个是满足这个的。
所以,用归并排序求一次正序对就好了。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=100007;
ll i,j,t,n,m,ans,k;
double a[maxn];
double l,r,mid,b[maxn],c[maxn],sum[maxn];
void msort(int l,int r){
int mid=(l+r)/2;
if(l==r)return;
msort(l,mid),msort(mid+1,r);
int i=l,j=mid+1,num=i-1;
while(i<=mid&&j<=r){
if(b[i]<=b[j])c[++num]=b[i],t+=r-j+1,i++;
else c[++num]=b[j],j++;
}
while(i<=mid)c[++num]=b[i],i++;
while(j<=r)c[++num]=b[j],j++;
fo(i,l,r)b[i]=c[i];
}
int main(){
freopen("ave.in","r",stdin);
freopen("ave.out","w",stdout);
scanf("%lld%lld",&n,&k);k=n*(n+1)/2+1-k;
fo(i,1,n)scanf("%lf",&a[i]);
fo(i,1,n)sum[i]=sum[i-1]+a[i];
l=0,r=1e9;
while(r-l>1e-5){
mid=(l+r)/2;
fo(i,0,n)b[i]=sum[i]-mid*i;
t=0;
msort(0,n);
if(t>=k)l=mid;else r=mid;
}
printf("%.4lf\n",l);
}