#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i=x;i<=y;++i)
#define repp(i,x,y) for(register int i=x;i>=y;--i)
#define db double
#define ll long long
#define ull unsigned long long
#define inf 1e9
#define mod 998244353
using namespace std;
inline int read() {int X=0;bool flag=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}if(flag) return X;return ~(X-1);}
inline void write(int X) {if(X<0) {X=~(X-1); putchar('-');}if(X>9) write(X/10);putchar(X%10+'0');}
inline int max(const int &x,const int &y){return x>y?x:y;}
inline int min(const int &x,const int &y){return x<y?x:y;}
inline int gcd(const int &x,const int &y){return y?gcd(y,x%y):x;}
inline int lcm(const int &x,const int &y){return x/gcd(x,y)*y;}
const int N=1e5;
int n,a[N+100];
db sum1[N+100],sum2[N+100],tag[N+100];
void pushup(int u) {
sum1[u]=sum1[u<<1]+sum1[u<<1+1];
sum2[u]=sum2[u<<1]+sum2[u<<1+1];
}
void maketag(int u,int len,db x) {
sum2[u]+=2.0*tag[u]*sum1[u]+len*tag[u]*tag[u];
sum1[u]+=len*x;
tag[u]+=x;
}
void pushdown(int u,int l,int r) {
int mid=(l+r)<<1;
maketag(u<<1,mid-l+1,tag[u]);
maketag(u<<1+1,r-mid,tag[u]);
tag[u]=0;
}
void build(int u,int l,int r) {
if(l==r) {
sum1[u]=a[l];
sum2[u]=a[l]*a[l];
return ;
}
int M=(l+r)>>1;
build(u<<1,l,M);
build(u<<1+1,M+1,r);
pushup(u);
}
db query1(int u,int L,int R,int l,int r) {
if(l<=L&&R<=r) return sum1[u];
if(!(L>r||R<l)) {
int M=(L+R)>>1;
pushdown(u,L,R);
return query1(u<<1,L,M,l,r)+query1(u<<1+1,M+1,R,l,r);
}else return 0;
}
db query2(int u,int L,int R,int l,int r) {
if(l<=L&&R<=r) return sum2[u];
if(!(L>r||R<l)) {
int M=(L+R)>>1;
pushdown(u,L,R);
return query2(u<<1,L,M,l,r)+query2(u<<1+1,M+1,R,l,r);
}else return 0;
}
void update(int u,int L,int R,int l,int r,db x) {
if(l<=L&&R<=r) maketag(u,R-L+1,x);
else if(!(L>r||R<l)) {
int M=(L+R)>>1;
pushdown(u,L,R);
update(u<<1,L,M,l,r,x);
update(u<<1+1,M+1,R,l,r,x);
pushup(u);
}
}
int main() {
n=read();
int T=read();
rep(i,1,n) a[i]=read();
build(1,1,n);
while(T--) {
int opt=read();
if(opt==1) {
int x=read(),y=read();
db ad=read();
update(1,x,y,1,n,ad);
}else if(opt==2) {
int x=read(),y=read();
printf("%.4lf\n",query1(1,x,y,1,n)/(y-x+1));
}else if(opt==3) {
int x=read(),y=read();
db s1=query1(1,x,y,1,n)/(y-x+1),s2=query2(1,x,y,1,n)/(y-x+1);
printf("%.4lf\n",s1-s2*s2);
}
}
return 0;
}