翻译
给出Q(Q<=5*10^5)个操作,共有两种操作 第一种操作输入两个数op
x:op表示第几种操作,x表示在当前序列中插入数x(x<=10^9),保证x大于当前序列中任意一个数
第二种操作输入一个数op:op表示第几种操作,求当前序列中的Maximize
定义Maximize为:在当前序列中找出一个子集,Maximize表示子集中数最大值/子集平均数的最大值 输出保留10位小数
题解
从来没有写过三分的我居然瞎写出了个三分哈哈哈
先贪心一下,每次一定会选当前最后插入的一个数
然后可以发现,平均值的函数实际上是一个下凸的函数
为什么?
设平均值为p,小于p的所有数都会拉低p的值,大于p的所有数都会拉高p的值
所以说这是一个下凸函数
下凸函数?当然三分最低点啊!
/*
翻译:
给出Q(Q<=5*10^5)个操作,共有两种操作
第一种操作输入两个数op x:op表示第几种操作,x表示在当前序列中插入数x(x<=10^9),保证x大于当前序列中任意一个数
第二种操作输入一个数op:op表示第几种操作,求当前序列中的Maximize
定义Maximize为:在当前序列中找出一个子集,Maximize表示子集中数最大值/子集平均数的最大值
输出保留10位小数
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
LL sum[510000],f[510000],list[510000];
int T,head;
int main()
{
head=0;
scanf("%d",&T);
while(T--)
{
int op;LL x;
scanf("%d",&op);
if(op==1)
{
scanf("%I64d",&list[++head]);
sum[head]=sum[head-1]+list[head];
}
else
{
int l=1,r=head;
while(l<r-1)
{
int mid=(l+r)/2;
int mmid=(mid+r)/2;
if((double)(list[head]+sum[mid])/(mid+1)>(double)(list[head]+sum[mmid])/(mmid+1))l=mid;
else r=mmid;
}
if((double)(list[head]+sum[l])/(l+1)>(double)(list[head]+sum[r])/(r+1))printf("%.10lf\n",(double)list[head]-(double)(list[head]+sum[r])/(r+1));
else printf("%.10lf\n",(double)list[head]-(double)(list[head]+sum[l])/(l+1));
}
}
return 0;
}