似乎在小数精度处出了一点问题
#include<iostream>
#include<cmath>
#define ll long long
using namespace std;
const int N=1e5+2;
double sum[4*N],add[4*N],res;
double ssum[4*N],sadd[4*N];
int n;
void build(int k,int l,int r){
if(l==r){
scanf("%lf",&sum[k]);
ssum[k]=sum[k]*sum[k];
return ;
}
int mid=(l+r)>>1;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
sum[k]=sum[k*2]+sum[k*2+1];
ssum[k]=ssum[k*2]+ssum[k*2+1];
return ;
}
void Add(int k,int l,int r,double v){
add[k]+=v;
sum[k]=sum[k]+(r-l+1)*v;
return ;
}
void sAdd(int k,int l,int r,double v){
sadd[k]+=v;
ssum[k]=ssum[k]+v*v*(r-l+1)+2*sum[k]*v;
return ;
}
void pushdown(int k,int l,int r){
if(add[k]==0)return ;
int mid=(l+r)>>1;
Add(k*2,l,mid,add[k]);
Add(k*2+1,mid+1,r,add[k]);
add[k]=0;
return ;
}
void spushdown(int k,int l,int r){
if(sadd[k]==0)return ;
int mid=(l+r)>>1;
sAdd(k*2,l,mid,sadd[k]);
sAdd(k*2+1,mid+1,r,sadd[k]);
sadd[k]=0;
return ;
}
void modify(int k,int l,int r,int x,int y,double v){
if(x<=l && y>=r){
Add(k,l,r,v);
return ;
}
pushdown(k,l,r);
int mid=(l+r)>>1;
if(x<=mid)modify(k*2,l,mid,x,y,v);
if(y>mid)modify(k*2+1,mid+1,r,x,y,v);
sum[k]=sum[k*2]+sum[k*2+1];
}
void smodify(int k,int l,int r,int x,int y,double v){
if(x<=l && y>=r){
sAdd(k,l,r,v);
return ;
}
spushdown(k,l,r);
int mid=(l+r)>>1;
if(x<=mid)smodify(k*2,l,mid,x,y,v);
if(y>mid)smodify(k*2+1,mid+1,r,x,y,v);
ssum[k]=ssum[k*2]+ssum[k*2+1];
}
double check(int k,int l,int r,int x,int y){
if(x<=l && y>=r){
return sum[k];
}
pushdown(k,l,r);
int mid=(l+r)>>1;
res=0;
if(x<=mid)res+=check(k*2,l,mid,x,y);
if(y>mid)res+=check(k*2+1,mid+1,r,x,y);
return res;
}
double scheck(int k,int l,int r,int x,int y){
if(x<=l && y>=r){
return ssum[k];
}
spushdown(k,l,r);
int mid=(l+r)>>1;
res=0;
if(x<=mid)res+=scheck(k*2,l,mid,x,y);
if(y>mid)res+=scheck(k*2+1,mid+1,r,x,y);
return res;
}
int m,x,y,f;
double k;
double pingjun,spingjun;
int main(){
scanf("%d %d",&n,&m);
build(1,1,n);
while(m--){
scanf("%d",&f);
if(f==1){
scanf("%d %d %lf",&x,&y,&k);
smodify(1,1,n,x,y,k);
modify(1,1,n,x,y,k);
}
if(f==2){
scanf("%d %d",&x,&y);
pingjun=double(check(1,1,n,x,y)/(y-x+1));
printf("%.4lf\n",pingjun);
}
if(f==3){
scanf("%d %d",&x,&y);
spingjun=double(scheck(1,1,n,x,y)/(y-x+1));
pingjun=double(check(1,1,n,x,y)/(y-x+1));
printf("%.4lf\n",spingjun-pingjun*pingjun);
}
}
return 0;
}