会输出负数,求助qwq
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=1e5+10;
int n,m;
double a[N];
#define ls p<<1
#define rs p<<1|1
struct tree{
int l,r;
double dat1,dat2,lazy;
}t[N<<2];
inline void pushup(int p){
t[p].dat1=(t[ls].dat1+t[rs].dat1);
t[p].dat2=(t[ls].dat2+t[rs].dat2);
}
inline void pushdown(int p){
if(t[p].lazy){
int mid=(t[p].l+t[p].r)>>1;
t[ls].dat2+=2*t[p].lazy*t[p].dat1+(mid-t[p].l+1)*t[p].lazy*t[p].lazy;
t[rs].dat2+=2*t[p].lazy*t[p].dat1+(t[p].r-mid)*t[p].lazy*t[p].lazy;
t[ls].dat1+=(mid-t[p].l+1)*t[p].lazy;
t[rs].dat1+=(t[p].r-mid)*t[p].lazy;
t[ls].lazy+=t[p].lazy;
t[rs].lazy+=t[p].lazy;
t[p].lazy=0;
}
}
void build(int p,int l,int r){
t[p].l=l,t[p].r=r;
if(l==r){
t[p].dat1=a[l];
t[p].dat2=t[p].dat1*t[p].dat1;
return ;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pushup(p);
}
void update(int p,int l,int r,double k){
if(l<=t[p].l&&t[p].r<=r){
t[p].dat2+=2*k*t[p].dat1+k*k*(r-l+1);
t[p].dat1+=(r-l+1)*k;
t[p].lazy+=k;
return ;
}pushdown(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid) update(ls,l,r,k);
if(mid+1<=r) update(rs,l,r,k);
pushup(p);
}
double query1(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r){
return t[p].dat1;
}pushdown(p);
double ans=0;
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid) ans+=query1(ls,l,r);
if(mid+1<=r) ans+=query1(rs,l,r);
return ans;
}
double query2(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r){
return t[p].dat2;
}pushdown(p);
double ans=0;
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid) ans+=query2(ls,l,r);
if(mid+1<=r) ans+=query2(rs,l,r);
return ans;
}
int op,x,y;
double k;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%lf",&a[i]);
build(1,1,n);
while(m--){
scanf("%d%d%d",&op,&x,&y);
if(op==1){
scanf("%lf",&k);
update(1,x,y,k);
}else if(op==2){
double ans1=query1(1,x,y)/(y-x+1);
printf("%.4lf\n",ans1);
}else{
double ans1=query1(1,x,y)/(y-x+1);
double ans2=query2(1,x,y)/(y-x+1);
printf("%.4lf\n",ans2-ans1*ans1);
}
}
return 0;
}