您的位置:首页 > 产品设计 > UI/UE

codeforces 283A. Cows and Sequence [线段树-区间更新]

2013-04-09 22:23 465 查看
题意:

对一个初始有1个元素0的 序列进行三种动态操作:

1. 前k个元素都加X

2. 在序列后增加一个元素X

3. 删除序列最后一个元素

要求每次操作后输出序列的平均值,保证每次操作后队列至少有1个元素,操作数少于20 0000次

思路:注意第一种操作是对前k个元素都加X,而第三种操作是删除最后一个元素,那么不可能简单地模拟了。于是用线段树,这里用到区间更新。

第一种操作,对1~k 区间增加X。第二种操作对n+1~n+1区间增加X。第三种操作先查询n~n的和s,再对n~n个元素增加 -s。

区间更新需要增加新变量inc,如果inc不等于0,表示这段区间的所有子区间都增加inc*区间长度

#include <iostream>
#include <cstdio>
#define N 200005
typedef long long LL;
struct Node
{
int a, b;
LL sum, inc;
Node() {}
Node(int _a, int _b): a(_a), b(_b), sum(0), inc(0) {}
int middle() { return (a+b)>>1; }
} t[N*4];
void build(int l, int r, int d)
{
if (l > r) return ;
t[d] = Node(l,r);
if (l == r) return ;
int mid = t[d].middle();
build(l,mid,d<<1);
build(mid+1,r,(d<<1)+1);
}
void update(int fo, int to, int v, int d)
{
t[d].sum += (to-fo+1)*v;
if (fo==t[d].a && t[d].b==to)
{
t[d].inc += v;
return ;
}
int mid = t[d].middle();
if (mid>=fo && mid<to)
{
update(fo,mid,v,d<<1);
update(mid+1,to,v,(d<<1)+1);
}
else if (mid < fo)
{
update(fo,to,v,(d<<1)+1);
}
else if (mid >= to)
{
update(fo,to,v,d<<1);
}
}
LL quary(int fo, int to, int d)
{
if (fo==t[d].a && to==t[d].b) return t[d].sum;
int mid = t[d].middle();
if (mid>=fo && mid<to) return quary(fo,mid,d<<1) + quary(mid+1,to,(d<<1)+1) + (to-fo+1)*t[d].inc;
else if (mid < fo) return quary(fo,to,(d<<1)+1) + (to-fo+1)*t[d].inc;
else if (mid >= to) return quary(fo,to,d<<1) + (to-fo+1)*t[d].inc;
}
int n, m, tag;
int main()
{
while (scanf("%d",&m) != EOF)
{
n = 1;
build(1,m+1,1);
while (m --)
{
scanf("%d",&tag);
if (tag == 1)
{
int to, v;
scanf("%d%d",&to,&v);
update(1,to,v,1);
}
else if (tag == 2)
{
int v;
n ++;
scanf("%d",&v);
update(n,n,v,1);
}
else
{
int v = int(quary(n,n,1));
update(n,n,-v,1);
n --;
}
printf("%.6lf\n", 1.0*quary(1,n,1)/n);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: