题目链接:
http://codeforces.com/problemset/problem/283/A
解法:
刚开始以为是简单的模拟,求平均数只需要知道sum和当前数组的长度即可。
每次进行操作1和2的时候都可以明确地增加sum的值。
但是后来发现进行操作3的时候要sum减去多少值不清楚,原因在于操作1的时候,对整个范围进行了加操作。
既然是对范围操作,有联想到用线段树来存储这个操作。
但是线段树写到一半突然意识到其实不用那么复杂。
主要原因在于:这个题目的场景操作是有序,对于操作3,始终都是从右边pop一个数字出去。
也就是说当pop a[i]的时候肯定已经pop过a[i+1]了。所以只需要新开辟一个数组d[] 来存储将操作1的加法状态即可。
每次进行操作3的时候 d[i-1]+=d[i],即可。
但是!
我的代码wa了,但是又查不出来哪里错误。
刚开始以为思路有误,后来搜了一下。发现
http://codeforces.com/blog/entry/7049
这个人和我解法一模一样。。。
实在查不出来哪写错了。先搁这了,以后再说了。
#include<iostream>
#include<fstream>
#include<map>
#include<vector>
#include<string>
#include<memory.h>
#include<cmath>
#include<algorithm>
#include<queue>
#define Min(a,b) (a<b?a:b)
#define Max(a,b) (a>b?a:b)
#define Abs(a) (a>0?(a):-(a))
#define llong long long int
using namespace std;
const int N=200005,M=100005,inf=0x7fffffff;
int n,m;
int a[N];
int d[N];
int p;
int sum;
int main()
{
//freopen("1.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
p=1;
sum=0;
memset(a,0,sizeof(a));
memset(d,0,sizeof(d));
int type,tmp;
for(int i=1;i<=n;i++)
{
scanf("%d",&type);
if(type==3)
{
sum -= a[p]+d[p];
if(d[p])
{
d[p-1]+=d[p];
}
d[p]=0;
a[p--]=0;
}
if(type==2)
{
scanf("%d",&tmp);
a[++p] = tmp;
sum += tmp;
}
if(type==1)
{
int fn,x;
scanf("%d%d",&fn,&x);
sum += fn*x;
d[fn]+=x;
}
printf("%lf\n",1.0*sum/p);
}
}
return 0;
}