import sys
sys.setrecursionlimit(100000000)
n,m=map(eval,input().split())
tree1=[0 for i in range(((n)<<2)+100)]#区间和
tree2=[0 for i in range((n<<2)+100)]#区间方的和
tag=[0 for i in range((n<<2)+100)]
num=[0]+list(map(eval,input().split()))
def pushup(x):
tree1[x]=tree1[x<<1]+tree1[x<<1|1]
tree2[x]=tree2[x<<1|1]+tree2[x<<1]
return
def build(x,l,r):
if (l==r):
tree1[x]=num[l]
tree2[x]=num[l]*num[l]
return
mid=(l+r)>>1
build(x<<1,l,mid)
build(x<<1|1,mid+1,r)
pushup(x)
build(1,1,n)
def pushdown(x,l,r):
mid=(l+r)>>1
tree2[x<<1]+=tree1[x<<1]*tag[x]*2+(mid-l+1)*tag[x]*tag[x]
tree2[x << 1|1] += tree1[x << 1|1] * tag[x] * 2 + (r-mid) * tag[x] * tag[x]
tree1[x<<1]+=(mid-l+1)*tag[x]
tree1[x<<1|1]+=(r-mid)*tag[x]
tag[x<<1]+=tag[x]
tag[x<<1|1]+=tag[x]
tag[x]=0
return
def update(x,l,r,a,b,k):
if (tag[x]!=0 and l!=r):
pushdown(x,l,r)
if (a<=l and r<=b):
tree2[x] +=tree1[x]*k*2+(r-l+1)*k*k
tree1[x]+=(r-l+1)*k
if (l!=r):tag[x]+=k
return
mid=(l+r)>>1
if (a<=mid):
update(x<<1,l,mid,a,b,k)
if (b>mid):
update(x<<1|1,mid+1,r,a,b,k)
pushup(x)
def query(x,l,r,a,b):
sum=0
if (tag[x]!=0 and l!=r):
pushdown(x,l,r)
if (a<=l and r<=b):
return tree1[x]
mid = (l + r) >> 1
if (a <= mid):
sum+=query(x << 1, l, mid, a, b)
if (b > mid):
sum+=query(x << 1 | 1, mid + 1, r, a, b)
return sum
def query1(x,l,r,a,b):
sum=0
if (tag[x]!=0 and l!=r):
pushdown(x,l,r)
if (a<=l and r<=b):
return tree2[x]
mid = (l + r) >> 1
if (a <= mid):
sum+=query1(x << 1, l, mid, a, b)
if (b > mid):
sum+=query1(x << 1 | 1, mid + 1, r, a, b)
return sum
for i in range(m):
mid=list(eval(int,input().split()))
if (mid[0]==1):
update(1,1,n,mid[1],mid[2],mid[3])
if (mid[0]==2):
print("{:.4f}".format(query(1, 1, n, mid[1], mid[2]) / (mid[2] - mid[1] + 1)))
if (mid[0]==3):
mm=query(1, 1, n, mid[1], mid[2]) / (mid[2] - mid[1] + 1)
m1=query1(1,1,n,mid[1],mid[2])/(mid[2] - mid[1] + 1)-mm*mm
print("{:.4f}".format(m1))