#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6;
double a[N],b[N];
double tr1[N],tr2[N];
double lazy[N];
inline void push_up(int id)
{
tr1[id]=tr1[id<<1]+tr1[id<<1|1];
tr2[id]=tr2[id<<1]+tr2[id<<1|1];
}
inline void push_down(int id,int l,int r)
{
int mid=(l+r)>>1;
lazy[id<<1]+=lazy[id];
lazy[id<<1|1]+=lazy[id];
tr2[id<<1]+=(lazy[id]*lazy[id])*(mid-l+1)+(2*lazy[id])*tr1[id<<1];
tr2[id<<1|1]+=(lazy[id]*lazy[id])*(r-mid)+(2*lazy[id])*tr1[id<<1|1];
tr1[id<<1]+=lazy[id]*(mid-l+1);
tr1[id<<1|1]+=lazy[id]*(r-mid);
lazy[id]=0;
}
inline void build(int id,int l,int r)
{
if(l==r)
{
tr1[id]=a[l];
tr2[id]=a[l]*a[l];
return;
}
int mid = (l+r)>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
push_up(id);
}
inline void update(int id,int l,int r,int x,int y,double v)
{
if(x<=l&&r<=y)
{
lazy[id]+=v;
tr2[id]+=(2*v)*tr1[id]+(v*v)*(r-l+1);
tr1[id]+=v*(r-l+1);
return;
}
int mid= (l+r) >>1;
push_down(id,l,r);
if(x<=mid)
{
update(id<<1,l,mid,x,y,v);
}
else
{
update(id<<1|1,mid+1,r,x,y,v);
}
push_up(id);
}
inline double find(int id,int l,int r,int x,int y,int n)
{
if(x<=l&&r<=y)
{
if(n==1)
{
return tr1[id];
}
if(n==2)
{
return tr2[id];
}
}
int mid =(l+r)>>1;
double all=0;
push_down(id,l,r);
if(x<=mid)
{
all+=find(id<<1,l,mid,x,y,n);
}
if(y>mid)
{
all+=find(id<<1|1,mid+1,r,x,y,n);
}
return all;
}
signed 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<=m;i++)
{
int x;
cin>>x;
if(x==1)
{
int y,z;
double k;
cin>>y>>z>>k;
update(1,1,n,y,z,k);
}
if(x==2)
{
int y,z;
cin>>y>>z;
double en = find(1,1,n,y,z,1)/((z-y+1)*1.0);
printf("%.4lf\n",en);
}
if(x==3)
{
int y,z;
cin>>y>>z;
//cout<<find(1,1,n,y,z,2)<<" "<<find(1,1,n,y,z,1)<<endl;
double l = find(1,1,n,y,z,2)/((z-y+1)*1.0)-(find(1,1,n,y,z,1)/((z-y+1)*1.0))*(find(1,1,n,y,z,1)/((z-y+1)*1.0));
printf("%.4lf\n",l);
}
}
}