方差
我现在才知道原来树状数组也叫分块......
#include<cmath> #include<cstdio> #include<cctype> #include<iostream> #include<algorithm> using namespace std;typedef long long LL; int L[401],R[401],n,q,l,r,opt,x,pos[100010],t; double d,a[100010],sum[401],add[401],sumaf[401]; inline long long read() { char c;int d=1;long long f=0; while(c=getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48; while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48; return d*f; } inline void write(register long long x) { if(x<0)putchar(45),x=-x; if(x>9)write(x/10); putchar(x%10+48); return; } double sqr(double x){return x*x;} void Add(register int l,register int r,double x) { int pl=pos[l],pr=pos[r]; if(pl==pr) { for(register int i=l;i<=r;i++) sumaf[pl]+=2*a[i]*x+sqr(x),a[i]+=x,sum[pl]+=x; return; } for(register int i=l;i<=R[pl];i++) sumaf[pl]+=2*a[i]*x+sqr(x),a[i]+=x,sum[pl]+=x; for(register int i=L[pr];i<=r;i++) sumaf[pr]+=2*a[i]*x+sqr(x),a[i]+=x,sum[pr]+=x; for(register int i=pl+1;i<pr;i++) add[i]+=x; return; } double ask(register int l,register int r) { int pl=pos[l],pr=pos[r],len=r-l+1; double ans=0; if(pl==pr) { for(register int i=l;i<=r;i++) ans+=a[i]+add[pl]; return ans/1.0/len; } else { for(register int i=l;i<=R[pl];i++) ans+=a[i]+add[pl]; for(register int i=L[pr];i<=r;i++) ans+=a[i]+add[pr]; for(register int i=pl+1;i<pr;i++) ans+=sum[i]+add[i]*t; return ans/1.0/len; } } double askfc(register int l,register int r) { int len=r-l+1,pl=pos[l],pr=pos[r];double ave=0,ans=0,answer=0; if(pl==pr) { for(register int i=l;i<=r;i++) ave+=a[i]+add[pl],ans+=sqr(a[i]+add[pl]); return ans/len-sqr(ave/len); } for(register int i=l;i<=R[pl];i++) ave+=a[i]+add[pl],ans+=sqr(a[i]+add[pl]); for(register int i=L[pr];i<=r;i++) ave+=a[i]+add[pr],ans+=sqr(a[i]+add[pr]); for(register int i=pl+1;i<pr;i++) ave+=sum[i]+add[i]*t,ans+=sumaf[i]+2*sum[i]*add[i]+t*sqr(add[i]); answer=ans/len-sqr(ave/len); return answer; } signed main() { freopen("1.txt","r",stdin); n=read();q=read();t=(int)sqrt(n)+1; for(register int i=1;i<=n;i++) scanf("%lf",a+i); for(register int i=1;i<=t;i++) { L[i]=R[i-1]+1,R[i]=min(R[i-1]+t,n); for(register int j=L[i];j<=R[i];j++) pos[j]=i,sum[i]+=a[j],sumaf[i]+=sqr(a[j]); } while(q--) { opt=read(); if(opt==1) { l=read();r=read();scanf("%lf",&d); Add(l,r,d); } if(opt==2) { l=read();r=read(); printf("%.4lf\n",ask(l,r)); } if(opt==3) { l=read();r=read(); printf("%.4lf\n",askfc(l,r)); } } }