代码
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e5+1;
struct node{
int l,r;double sum,tag,sum2;
}tre[N*4];
double a[N];int n,m;
int ls(int x){return x<<1;}
int rs(int x){return x<<1|1;}
void ps(int x){
tre[x].sum=tre[rs(x)].sum+tre[ls(x)].sum;
tre[x].sum2=tre[rs(x)].sum2+tre[ls(x)].sum2;
}
void bui(int x){
if(x==1){tre[x].l=1;tre[x].r=n;}
if(tre[x].l==tre[x].r){
tre[x].sum=a[tre[x].l];
tre[x].sum2=tre[x].sum*tre[x].sum;
return ;
}
int mid=(tre[x].l+tre[x].r)>>1;
tre[ls(x)].l=tre[x].l;
tre[ls(x)].r=mid;
tre[rs(x)].l=mid+1;
tre[rs(x)].r=tre[x].r;
bui(ls(x));
bui(rs(x));
ps(x);
}
void f(int x,double k){
tre[x].sum2+=k*k*(1.0*(tre[x].r-tre[x].l+1))+tre[x].sum*2.0*k;
tre[x].sum+=k*(1.0*(tre[x].r-tre[x].l+1));
tre[x].tag+=k;
}
void pd(int x){
f(ls(x),tre[x].tag);
f(rs(x),tre[x].tag);
tre[x].tag =0;
}
void ch(int ll,int rr,int x,double k){
if(ll<=tre[x].l&&tre[x].r<=rr){f(x,k);return;}
int mid=(tre[x].l+tre[x].r)>>1;
pd(x);
if(mid>=ll) ch(ll,rr,ls(x),k);
if(mid+1<=rr) ch(ll,rr,rs(x),k);
ps(x);
}
double qs(int ll,int rr,int x){
double ans=0;
if(ll<=tre[x].l&&tre[x].r<=rr){return tre[x].sum;}
int mid=(tre[x].l+tre[x].r)>>1;
pd(x);
if(mid>=ll) ans+=qs(ll,rr,ls(x));
if(mid+1<=rr) ans+=qs(ll,rr,rs(x));
return ans;
}
double qs2(int ll,int rr,int x){
double ans=0;
if(ll<=tre[x].l&&tre[x].r<=rr){return tre[x].sum2;}
int mid=(tre[x].l+tre[x].r)>>1;
pd(x);
if(mid>=ll) ans+=qs(ll,rr,ls(x));
if(mid+1<=rr) ans+=qs(ll,rr,rs(x));
return ans;
}
int main(){
double ansc,ansp;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
bui(1);
for(int i=1;i<=m;i++){
int c,ll,rr;
double k;
cin>>c;
if(c==1) {
cin>>ll>>rr>>k;
ch(ll,rr,1,k);
}
if(c==2){
cin>>ll>>rr;
ansc=qs(ll,rr,1)/(1.0*(rr-ll+1));
printf("%.4lf\n",ansc);
}
if(c==3){
cin>>ll>>rr;
ansc=qs(ll,rr,1)/(1.0*(rr-ll+1));
ansp=qs2(ll,rr,1)/(1.0*(rr-ll+1));
printf("%.4lf\n",ansp-ansc*ansc);
}
}
return 0;
}