RT,维护 区间平方和 和 区间和,全 WA 求助/kel
#include<cstdio>
typedef double db;
const int M=1e5+5;
int n,m;
db val,a[M];
struct Node{
db sum,squ,tag;
inline Node operator+(const Node&it)const{
return (Node){sum+it.sum,squ+it.squ,0};
}
}tmp,t[M<<2];
inline void update(const int&u){
t[u]=t[u<<1]+t[u<<1|1];
}
inline void pushdown(const int&u,const int&L,const int&R){
if(!t[u].tag)return;
int mid=L+R>>1;
const int&k=t[u].tag;
t[u<<1].squ+=k*k*(mid-L+1)+2*k*t[u<<1].sum;
t[u<<1|1].squ+=k*k*(R-mid)+2*k*t[u<<1|1].sum;
t[u<<1].tag+=t[u].tag;t[u<<1].sum+=(mid-L+1)*t[u].tag;
t[u<<1|1].tag+=t[u].tag;t[u<<1|1].sum+=(R-mid)*t[u].tag;
t[u].tag=0;
}
void build(int u,int L,int R){
if(L==R)t[u].sum=a[L],t[u].squ=1ll*a[L]*a[L];
else{
int mid=L+R>>1;
build(u<<1,L,mid);build(u<<1|1,mid+1,R);
update(u);
}
}
void Modify(int u,int l,int r,db val,int L=1,int R=n){
if(L>r||l>R)return;
if(l<=L&&R<=r){
t[u].tag+=val;
t[u].squ+=val*val*(R-L+1)+2*val*t[u].sum;
t[u].sum+=val*(R-L+1);
return;
}
int mid=L+R>>1;
pushdown(u,L,R);
Modify(u<<1,l,r,val,L,mid);Modify(u<<1|1,l,r,val,mid+1,R);
update(u);
}
Node Query(int u,int l,int r,int L=1,int R=n){
if(L>r||l>R)return (Node){0,0,0};
if(l<=L&&R<=r)return t[u];
int mid=L+R>>1;
pushdown(u,L,R);
return Query(u<<1,l,r,L,mid)+Query(u<<1|1,l,r,mid+1,R);
}
signed main(){
register int i,f,L,R;
scanf("%d%d",&n,&m);
for(i=1;i<=n;++i)scanf("%lf",a+i);
build(1,1,n);
for(i=1;i<=m;++i){
scanf("%d%d%d",&f,&L,&R);
if(f==1){
scanf("%lf",&val);
Modify(1,L,R,val);
}
else if(f==2){
printf("%.4lf\n",Query(1,L,R).sum/(R-L+1));
}
else{
tmp=Query(1,L,R);
val=tmp.sum/(R-L+1);
printf("%.4lf\n",(tmp.squ-2*val*tmp.sum)/(R-L+1)+val*val);
}
}
}