AC日记——方差 洛谷 P1471
思路:
线段树;
代码:
#include <bits/stdc++.h> using namespace std; #define maxn 100005 struct TreeNodeType { int l,r,mid,size; double sum,sum2,flag; inline void updata(double x) { flag+=x; sum2+=sum*x*2+size*x*x; sum+=x*size; } }; struct TreeNodeType tree[maxn<<2]; int n,m; double X,Sum,Sum2; inline void in(int &now) { int if_z=1;now=0; char Cget=getchar(); while(Cget>'9'||Cget<'0') { if(Cget=='-') if_z=-1; Cget=getchar(); } while(Cget>='0'&&Cget<='9') { now=now*10+Cget-'0'; Cget=getchar(); } now*=if_z; } void build(int now,int l,int r) { tree[now].l=l,tree[now].r=r,tree[now].size=r-l+1; if(l==r) { scanf("%lf",&tree[now].sum); tree[now].sum2=tree[now].sum*tree[now].sum; return; } tree[now].mid=l+r>>1; build(now<<1,l,tree[now].mid); build(now<<1|1,tree[now].mid+1,r); tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum; tree[now].sum2=tree[now<<1].sum2+tree[now<<1|1].sum2; } inline void pushdown(int now) { tree[now<<1].updata(tree[now].flag); tree[now<<1|1].updata(tree[now].flag); tree[now].flag=0; } void operation1(int now,int l,int r) { if(tree[now].l>=l&&tree[now].r<=r) { tree[now].updata(X); return; } if(tree[now].flag) pushdown(now); if(l<=tree[now].mid) operation1(now<<1,l,r); if(r>tree[now].mid) operation1(now<<1|1,l,r); tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum; tree[now].sum2=tree[now<<1].sum2+tree[now<<1|1].sum2; } void operation2(int now,int l,int r) { if(tree[now].l>=l&&tree[now].r<=r) { Sum+=tree[now].sum; Sum2+=tree[now].sum2; return; } if(tree[now].flag) pushdown(now); if(l<=tree[now].mid) operation2(now<<1,l,r); if(r>tree[now].mid) operation2(now<<1|1,l,r); } int main() { in(n),in(m),build(1,1,n); int op,l,r; while(m--) { in(op),in(l),in(r); if(op==1) scanf("%lf",&X),operation1(1,l,r); if(op==2) Sum=0,operation2(1,l,r),printf("%.4lf\n",Sum/(r-l+1)); if(op==3) { Sum=0,Sum2=0; operation2(1,l,r); X=Sum/(r-l+1); printf("%.4lf\n",(Sum2-Sum*X*2+(r-l+1)*X*X)/(r-l+1)); } } return 0; }