#include<bits/stdc++.h>
using namespace std;
int n,m,x,y;
double a[100002],k;
struct node
{
double nue1,le,ri,nue2,lazy;
}t[400004];
void init(int ne,int l,int r)
{
t[ne].le=l;
t[ne].ri=r;
if(l==r)
{
t[ne].nue1=a[l];
t[ne].nue2=a[l]*a[l];
return;
}
int mid=(l+r)/2;
init(ne*2,l,mid);
init(ne*2+1,mid+1,r);
t[ne].nue1=t[ne*2].nue1+t[ne*2+1].nue1;
t[ne].nue2=t[ne*2].nue2+t[ne*2+1].nue2;
return;
}
void push(int ne,int l,int r)
{
t[ne*2].nue2+=(r-l+1)*t[ne].lazy*t[ne].lazy+2*t[ne].lazy*t[ne*2].nue1;
t[ne*2].nue1+=(r-l+1)*t[ne].lazy;
t[ne*2+1].nue2+=(r-l+1)*t[ne].lazy*t[ne].lazy+2*t[ne].lazy*t[ne*2+1].nue1;
t[ne*2+1].nue1+=(r-l+1)*t[ne].lazy;
t[ne*2].lazy+=k;
t[ne*2+1].lazy+=k;
}
void add(int ne,int l,int r)
{
if(l>=x&&r<=y)
{
t[ne].nue2+=(r-l+1)*k*k+2*k*t[ne].nue1;
t[ne].nue1+=(r-l+1)*k;
t[ne].lazy+=k;
return;
}
if(t[ne].lazy!=0)
{
push(ne,l,r);
}
int mid=(l+r)/2;
if(x<=mid)
{
add(ne*2,l,mid);
}
if(y>=mid+1)
{
add(ne*2+1,mid+1,r);
}
t[ne].nue1=t[ne*2].nue1+t[ne*2+1].nue1;
t[ne].nue2=t[ne*2].nue2+t[ne*2+1].nue2;
return;
}
double f1(int ne,int l,int r)
{
if(l>=x&&r<=y)
{
return t[ne].nue1;
}
if(t[ne].lazy!=0)
{
push(ne,l,r);
}
double mid=(l+r)/2,sum=0;
if(x<=mid)
{
sum+=f1(ne*2,l,mid);
}
if(y>=mid+1)
{
sum+=f1(ne*2+1,mid+1,r);
}
return sum;
}
double f2(int ne,int l,int r)
{
if(l>=x&&r<=y)
{
return t[ne].nue2;
}
if(t[ne].lazy!=0)
{
push(ne,l,r);
}
double mid=(l+r)/2,sum=0;
if(x<=mid)
{
sum+=f2(ne*2,l,mid);
}
if(y>=mid+1)
{
sum+=f2(ne*2+1,mid+1,r);
}
return sum;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
init(1,1,n);
for(int i=1;i<=m;i++)
{
int pu;
cin>>pu;
if(pu==1)
{
cin>>x>>y>>k;
add(1,1,n);
}
else if(pu==2)
{
cin>>x>>y;
printf("%.4lf",f1(1,1,n)*1.0/(y-x+1));
cout<<"\n";
}
else
{
cin>>x>>y;
double ff1=f1(1,1,n)*1.0/(y-x+1);
double ff2=f2(1,1,n)*1.0/(y-x+1);
printf("%.4lf",ff2-ff1*ff1);
cout<<"\n";
}
}
return 0;
}