样例最后一个输出错了。
#include<bits/stdc++.h>
#define ls x<<1
#define rs x<<1|1
#define int long long
using namespace std;
int n,m;
const int MAXN=4e5+5;
double a[MAXN];
double sum[MAXN];
double pf[MAXN];
double tag[MAXN];
void pushup(int x){
sum[x]=sum[ls]+sum[rs];
pf[x]=pf[ls]+pf[rs];
return;
}
void build(int x,int l,int r){
tag[x]=0;
if(l==r){
sum[x]=a[l];
pf[x]=a[l]*a[l];
return;
}
int mid=l+r>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pushup(x);
return;
}
void pushdown(int x,int l,int r){
if(tag[x]==0){
return;
}
int mid=l+r>>1;
tag[ls]+=tag[x];
tag[rs]+=tag[x];
pf[ls]+=(2*sum[ls]*tag[x]+tag[x]*tag[x]*(mid-l+1));
pf[rs]+=(2*sum[ls]*tag[x]+tag[x]*tag[x]*(r-mid));
sum[ls]+=tag[x]*(mid-l+1);
sum[rs]+=tag[x]*(r-mid);
tag[x]=0;
return;
}
void add(int x,int l,int r,int L,int R,double k){
if(L<=l&&r<=R){
tag[x]+=k;
pf[x]+=(2*sum[x]*k+k*k*(r-l+1));
sum[x]+=(r-l+1)*x;
return;
}
pushdown(x,l,r);
int mid=l+r>>1;
if(L<=mid){
add(ls,l,mid,L,R,k);
}
if(R>mid){
add(rs,mid+1,r,L,R,k);
}
pushup(x);
return;
}
double query(int x,int l,int r,int L,int R){
if(L>r||R<l)return 0.0000;
if(L<=l&&r<=R){
return sum[x];
}
pushdown(x,l,r);
int mid=l+r>>1;
double ret=0;
if(L<=mid){
ret+=query(ls,l,mid,L,R);
}
if(R>mid){
ret+=query(rs,mid+1,r,L,R);
}
return ret;
//ret is the sum
}
double querypf(int x,int l,int r,int L,int R){
if(L>r||R<l)return 0.0000;
if(L<=l&&R>=r){
return pf[x];
}
pushdown(x,l,r);
int mid=l+r>>1;
double ret=0;
if(L<=mid){
ret+=querypf(ls,l,mid,L,R);
}
if(R>mid){
ret+=querypf(rs,mid+1,r,L,R);
}
return ret;
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
for(int i=1;i<=m;i++){
int opt;
cin>>opt;
if(opt==1){
int x,y;
double z;
cin>>x>>y>>z;
add(1,1,n,x,y,z);
}
if(opt==2){
int x,y;
cin>>x>>y;
printf("%.4lf\n",query(1,1,n,x,y)*1.0/(y-x+1.0));
}
if(opt==3){
int x,y;
cin>>x>>y;
double avg=query(1,1,n,x,y)*1.0/(y-x+1.0);
double sq=querypf(1,1,n,x,y)*1.0/(y-x+1.0);
// cout<<avg<<" "<<sq<<endl;
printf("%.4lf\n",sq-avg*avg);
}
}
return 0;
}