洛谷P1471 方差 发表于 2018-06-15 | 分类于 OI 字数统计: 606 | 阅读时长 ≈ 4 区间修改,区间查询,基本可以用线段树维护,主要是方差比较难维护将方差的计算展开 对于区间加法 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788#include<cstdio>#include<algorithm>#include<cmath>using namespace std;const int N=100050;const double eps=1e-8;int n,m,ql,qr;struct node {double val,sum,c;} t[N<<2]; double sqr(double x) {return x*x;}void build(int o,int l,int r){ if (l==r) { scanf("%lf",&t[o].val); t[o].sum=sqr(t[o].val); return; } int mid=(l+r)>>1; build(o<<1,l,mid); build(o<<1|1,mid+1,r); t[o].val=t[o<<1].val+t[o<<1|1].val; t[o].sum=t[o<<1].sum+t[o<<1|1].sum;}void pushdown(int o,int l,int r){ double x=t[o].c;t[o].c=0; int mid=(l+r)>>1; t[o<<1].sum+=(mid-l+1)*sqr(x)+2*x*t[o<<1].val; t[o<<1|1].sum+=(r-mid)*sqr(x)+2*x*t[o<<1|1].val; t[o<<1].val+=(mid-l+1)*x; t[o<<1|1].val+=(r-mid)*x; t[o<<1].c+=x,t[o<<1|1].c+=x; }void update(int o,int l,int r,double x){ if (ql<=l&&r<=qr) { t[o].sum+=sqr(x)*(r-l+1)+2*x*t[o].val; t[o].val+=(r-l+1)*x;t[o].c+=x; return; } int mid=(l+r)>>1; if (fabs(t[o].c)>eps) pushdown(o,l,r); if (ql<=mid) update(o<<1,l,mid,x); if (qr>mid) update(o<<1|1,mid+1,r,x); t[o].val=t[o<<1].val+t[o<<1|1].val; t[o].sum=t[o<<1].sum+t[o<<1|1].sum;}double ask(int o,int l,int r){ if (ql<=l&&r<=qr) return t[o].val; int mid=(l+r)>>1;double ret=0; if (fabs(t[o].c)>eps) pushdown(o,l,r); if (ql<=mid) ret+=ask(o<<1,l,mid); if (qr>mid) ret+=ask(o<<1|1,mid+1,r); return ret;}double query(int o,int l,int r){ if (ql<=l&&r<=qr) return t[o].sum; int mid=(l+r)>>1;double ret=0; if (fabs(t[o].c)>eps) pushdown(o,l,r); if (ql<=mid) ret+=query(o<<1,l,mid); if (qr>mid) ret+=query(o<<1|1,mid+1,r); return ret;}int main(){ scanf("%d%d",&n,&m); build(1,1,n); for(int i=1;i<=m;i++) { int opt; scanf("%d%d%d",&opt,&ql,&qr); if (opt==1) { double x;scanf("%lf",&x); update(1,1,n,x); } if (opt==2) printf("%.4lf\n",ask(1,1,n)/(qr-ql+1)); if (opt==3) { double x=ask(1,1,n)/(qr-ql+1); printf("%.4lf\n",-sqr(x)+query(1,1,n)/(qr-ql+1)); } } return 0;}