pushdown和change可能出了点问题TAT
#include<iostream>
#include<cstdio>
using namespace std;
struct node{
int l,r;
double sum,sum2,lazy;
}d[400005];
double a[100005];
void build(int p,int l,int r){
d[p].l=l,d[p].r=r;
if(l==r){
d[p].sum=a[l];
d[p].sum2=a[l]*a[l];
return ;
}
int mid=l+r>>1;
build(p*2+1,mid+1,r);
build(p*2,l,mid);
d[p].sum=d[p*2].sum+d[p*2+1].sum;
d[p].sum2=d[p*2].sum2+d[p*2+1].sum2;
}
void pushdown(int p){
if(!d[p].lazy)return;
else {
double k=d[p].lazy;
d[p*2].sum2+=2*k*d[p*2].sum+(d[p*2].r-d[p*2].l+1)*k*k;
d[p*2+1].sum2+=2*k*d[p*2+1].sum+(d[p*2+1].r-d[p*2+1].l+1)*k*k;
d[p*2].sum+=(d[p*2].r-d[p*2].l+1)*k;
d[p*2+1].sum+=(d[p*2+1].r-d[p*2+1].l+1)*k;
d[p*2].lazy+=k,d[p*2+1].lazy+=k;
d[p].lazy=0;
}
}
void change(int p,int l,int r,double k){
//cout<<l<<" "<<r<<endl;
if(d[p].l>=l&&d[p].r<=r){
// cout<<p<<endl;
d[p].sum2+=2*k*d[p].sum+(d[p].r-d[p].l+1)*k*k;
d[p].sum+=(d[p].r-d[p].l+1)*k;
d[p].lazy+=k;
return ;
}
pushdown(p);
int mid=d[p].l+d[p].r>>1;
if(mid>=l)change(p*2,l,r,k);
if(mid<r)change(p*2+1,l,r,k);
d[p].sum=d[p*2].sum+d[p*2+1].sum;
d[p].sum2=d[p*2].sum2+d[p*2+1].sum2;
}
double getsum1(int p,int l,int r){
//cout<<p<<" ";
if(d[p].l>=l&&d[p].r<=r){
return d[p].sum;
}
pushdown(p);
int mid=(d[p].l+d[p].r)/2;
//cout<<d[p].l<<" "<<d[p].r<<" "<<r<<" "<<mid<<endl;
double s=0;
if(mid<r)s+=getsum1(p*2+1,l,r);
if(mid>=l)s+=getsum1(p*2,l,r);
return s;
}
double getsum2(int p,int l,int r){
// cout<<p<<" "<<d[p].sum2<<endl;
if(d[p].l>=l&&d[p].r<=r){
return d[p].sum2;
}
pushdown(p);
int mid=(d[p].l+d[p].r)/2;
double s2=0;
if(mid<r)s2+=getsum1(p*2+1,l,r);
if(mid>=l)s2+=getsum1(p*2,l,r);
return s2;
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
// for(int i=1;i<=2*n;i++)cout<<d[i].sum2<<endl;
for(int i=1;i<=m;i++){
//for(int i=1;i<=2*n;i++)cout<<d[i].sum<<" "<<d[i].sum2<<endl;
double b,x,y;
double k;
cin>>b;
if(b==1){
cin>>x>>y>>k;
change(1,x,y,k);
}
else if(b==2){
cin>>x>>y;
double cnt=double(getsum1(1,x,y));
double ans=double(double(cnt)/double(y-x+1));
printf("%.4lf\n",ans);
}
else if(b==3){
cin>>x>>y;
double ans=double(getsum1(1,x,y))/double(y-x+1)*double(getsum1(1,x,y))/double(y-x+1);
double ans2=double(getsum2(1,x,y))/double(y-x+1)-ans;
// cout<<getsum2(1,x,y)<<endl;
printf("%.4lf\n",ans2);
}
}
}