解题思路:很容易想到,最大值肯定是用当前s的最大值减去某个从前往后取的子集。想是想到了,但是不会……因为没学过三分搜索。这里顺便学习了三分搜索,学会了就很简单了!推荐:https://blog.csdn.net/u011787119/article/details/44598871
边缘条件要注意。
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const int MOD=1e9+7;
double s[500005];
int cnt;
double sum[500005];
double judge(int x,int m){
return s[m]-(sum[x]+s[m])/(x+1);
}
int tri_search(int N){
int ml,mr;
int l=1,r=N-1;
while(l+1<r){
ml=(l+r)/2;
mr=(ml+r)/2;
if(judge(ml,N)>=judge(mr,N))
r=mr;
else
l=ml;
}
if(judge(l,N)>judge(r,N))//边缘情况
return l;
else
return r;
}
int main()
{
int Q;
scanf("%d",&Q);
cnt=0;
int a,b;
while(Q--){
scanf("%d",&a);
if(a==1){
scanf("%d",&b);
cnt++;
s[cnt]=b;
sum[cnt]=sum[cnt-1]+s[cnt];
}
else{
if(cnt==1){
printf("%.10lf\n",0.0);
}
else
if(cnt==2){
printf("%.10lf\n",s[2]-(sum[1]+s[2])/(2));
}
else{
if(cnt==3){
double one=s[3]-(sum[1]+s[2]+s[3])/(3);
double two=s[3]-(sum[1]+s[3])/(2);
printf("%.10lf\n",max(one,two));
}
else{
int index=tri_search(cnt);
printf("%.10lf\n",s[cnt]-(sum[index]+s[cnt])/(index+1));
}
}
}
}
return 0;
}