#include "bits/stdc++.h"
using namespace std;
const int MAXN = 1e5 + 5;
int n , m , opt , x , y;
double a[MAXN] , t1[MAXN << 2] , t2[MAXN << 2] , tag1[MAXN << 2] , tag2[MAXN << 2] , k;
int ls(int p) {return p << 1;}
int rs(int p) {return (p << 1) + 1;}
void push_up(int p)
{
t1[p] = t1[ls(p)] + t1[rs(p)];
t2[p] = t2[ls(p)] + t2[rs(p)];
return;
}
void build(int p , int l , int r)
{
if (l == r) {t1[p] = a[l]; t2[p] = a[l] * a[l]; return;}
int mid = (l + r) >> 1;
build(ls(p) , l , mid);
build(rs(p) , mid + 1 , r);
push_up(p);
return;
}
void add_tag1(int p , int l , int r , double d)
{
tag1[p] += d;
t1[p] += (r - l + 1) * d;
return;
}
void push_down1(int p , int l , int r)
{
int mid = (l + r) >> 1;
add_tag1(ls(p) , l , mid , tag1[p]);
add_tag1(rs(p) , mid + 1 , r , tag1[p]);
tag1[p] = 0;
return;
}
double query1(int x , int y , int p , int l , int r)
{
if (x <= l && r <= y) return t1[p];
push_down1(p , l , r);
int mid = (l + r) >> 1;
double ans = 0;
if (x <= mid) ans += query1(x , y , ls(p) , l , mid);
if (y > mid) ans += query1(x , y , rs(p) , mid + 1 , r);
return ans;
}
void add_tag2(int p , int l , int r , double d)
{
tag2[p] += d;
t2[p] += 2 * d * query1(l , r , 1 , 1 , n) + (r - l + 1) * d * d;
return;
}
void push_down2(int p , int l , int r)
{
int mid = (l + r) >> 1;
add_tag2(ls(p) , l , mid , tag2[p]);
add_tag2(rs(p) , mid + 1 , r , tag2[p]);
tag2[p] = 0;
return;
}
void update2(int x , int y , int p , int l , int r , double d)
{
if (x <= l && r <= y)
{
add_tag2(p , l , r , d);
return;
}
push_down2(p , l , r);
int mid = (l + r) >> 1;
if (x <= mid) update2(x , y , ls(p) , l , mid , d);
if (y > mid) update2(x , y , rs(p) , mid + 1 , r , d);
push_up(p);
return;
}
void update1(int x , int y , int p , int l , int r , double d)
{
if (x <= l && r <= y)
{
add_tag1(p , l , r , d);
return;
}
push_down1(p , l , r);
int mid = (l + r) >> 1;
if (x <= mid) update1(x , y , ls(p) , l , mid , d);
if (y > mid) update1(x , y , rs(p) , mid + 1 , r , d);
push_up(p);
return;
}
double query2(int x , int y , int p , int l , int r)
{
if (x <= l && r <= y) return t2[p];
push_down2(p , l , r);
int mid = (l + r) >> 1;
double ans = 0;
if (x <= mid) ans += query2(x , y , ls(p) , l , mid);
if (y > mid) ans += query2(x , y , rs(p) , mid + 1 , r);
return ans;
}
int main()
{
cin >> n >> m;
for (int i = 1 ; i <= n ; i++) cin >> a[i];
build(1 , 1 , n);
while (m--)
{
cin >> opt >> x >> y;
if (opt == 1)
{
cin >> k;
update2(x , y , 1 , 1 , n , k);
update1(x , y , 1 , 1, n , k);
}
else if (opt == 2)
{
cout << fixed << setprecision(4) << query1(x , y , 1 , 1 , n) / (y - x + 1) << '\n';
}
else
{
cout << fixed << setprecision(4) << query2(x , y , 1 , 1 , n) / (y - x + 1) - (query1(x , y , 1 , 1 , n) / (y - x + 1)) * (query1(x , y , 1 , 1 , n) / (y - x + 1)) << '\n';
}
}
return 0;
}