题目
LYK有一个长度为n的序列a。
他最近在研究平均数。
他甚至想知道所有区间的平均数,但是区间数目实在太多了。
为了方便起见,你只要告诉他所有区间(n*(n+1)/2个区间)中第k大的平均数就行了。
Input
第一行两个数n,k(1<=n<=100000,1<=k<=n*(n+1)/2)。
接下来一行n个数表示LYK的区间(1<=ai<=100000)。
Output
一行表示第k大的平均数,误差不超过1e-4就算正确。
Input示例
5 3
1 2 3 4 5
Output示例
4.000
题解
首先看到这种平均数我们很套路的想到二分
我们先看一下在什么时候(i,j)有贡献,设当前二分值为mid
sum[j]−sum[i]j−i>mid时(i,j)的平均数就比mid大,此时有贡献
那么我们可以移一下项,得:sum[i]−mid∗i<sum[j]−mid∗j
那么我们预处理这个东西然后搞一下二维偏序就好了
注意0也要加进去
贴代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define db double
#define ll long long
using namespace std;
const int maxn=10005,md=100000007;
struct node{
db x,y,z;
}a[maxn],b[maxn];
int i,j;
ll p,ans,c,ge,nt,k,n;
ll cc[maxn];
int cmp(node x,node y){
return x.z<y.z;
}
bool check(node x,node y){
return x.x*y.y>x.y*y.x;
}
int main(){
freopen("forgive.in","r",stdin);
freopen("forgive.out","w",stdout);
scanf("%d%d",&n,&p);
for (i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
cc[0]=1;
c=(p*p)%md;
for (i=1;i<=n;i++) cc[i]=(cc[i-1]*(1-p+md))% md;
ans=3*(n*p+cc[n])-3;
ans=ans%md;
nt=n-1;
for (i=1;i<=n;i++){
for (j=1;j<=n;j++){
b[j].x=a[j].x-a[i].x;
b[j].y=a[j].y-a[i].y;
b[j].z=atan2(b[j].y,b[j].x);
if (i==j) b[i].z=21474844;
}
sort(b+1,b+n+1,cmp);
k=1;
ge=0;
for (j=1;j<=nt;j++){
while (check(b[j],b[k%nt+1])) {
ge++;
k=k%nt+1;
}
ans=(ans-(cc[n-ge-2]*c)%md+md)% md;
if (ge) ge--; else k=k%nt+1;
}
}
printf("%d",ans);
return 0;
}