You are given a multiset S consisting of positive integers (initially empty). There are two kind of queries:
- Add a positive integer to S, the newly added integer is not less than any number in it.
- Find a subset s of the set S such that the value
is maximum possible. Here max(s) means maximum value of elements in s,
— the average value of numbers in s. Output this maximum possible value of
.
The first line contains a single integer Q (1 ≤ Q ≤ 5·105) — the number of queries.
Each of the next Q lines contains a description of query. For queries of type 1 two integers 1 and x are given, where x (1 ≤ x ≤ 109) is a number that you should add to S. It's guaranteed that x is not less than any number in S. For queries of type 2, a single integer 2 is given.
It's guaranteed that the first query has type 1, i. e. S is not empty when a query of type 2 comes.
Output the answer for each query of the second type in the order these queries are given in input. Each number should be printed in separate line.
Your answer is considered correct, if each of your answers has absolute or relative error not greater than 10 - 6.
Formally, let your answer be a, and the jury's answer be b. Your answer is considered correct if .
6 1 3 2 1 4 2 1 8 2
0.0000000000 0.5000000000 3.0000000000
4 1 1 1 4 1 5 2
2.0000000000
题意:给出n个操作,操作1往集合中插入元素x,操作2查询答案
查询的答案为所有子集中 max(最大元素-平均值)
分析:首先是贪心考虑什么情况下查询所得最大,肯定是只选一个最大值,然后一直选较小值使得平均数减小
根据题目,我们可以发现随着元素的插入,所查询的答案是递增的(因为没有删除操作,原有的答案一定可以找出一个子集包含),此时所得的答案就可以从原有的答案中得来(可以这样考虑,比如当前最大值是max1,然后又插入了个比它大的max2,前面所求得的子集对max1而言都可以使平均数减小,那么max2更是如此),所以每次查询时用到的数可以直接删除,然后每次根据新加入的数字不断更新即可,具体看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<ll,ll>t;
priority_queue<int,vector<int>,greater<int> >q;
int main()
{
ll n,x,op,maxx=0,num=0,sum=0;
double ans=0;
scanf("%lld",&n);
while(n--)
{
scanf("%lld",&op);
if(op==1)
{
scanf("%lld",&x);
if(!t[x])q.push(x),maxx=max(maxx,x);
t[x]++;
}
else
{
ans=max(ans,maxx-(maxx+sum)*1.0/(num+1));//直接利用之前最优的子集
while(!q.empty())//求得当前最优子集
{
x=q.top();
q.pop();
if(maxx-(maxx+sum+t[x]*x)*1.0/(t[x]+num+1)>ans)
{
ans=maxx-(maxx+sum+t[x]*x)*1.0/(t[x]+num+1);
sum+=t[x]*x;
num+=t[x];
t[x]=0;
}
else
{
//没用到该元素,后面比它大的元素肯定不会再用到
q.push(x);
break;
}
}
printf("%.6f\n",ans);
}
}
return 0;
}