rt
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define leftson (p<<1)
#define Mid ((l+r)>>1)
#define mid ((tree[p].l+tree[p].r)>>1)
#define rightson (p<<1|1)
const int N = 2e6+5;
int n,m;
double arr[N];
struct node { int l,r; double ans,power,tag; }tree[N];
inline void build(int p,int l,int r) {
	
	tree[p].l = l; tree[p].r = r;
	if(l == r) { tree[p].ans = arr[l]; tree[p].power = arr[l] * arr[l]; return; }
	build(leftson,l,Mid); build(rightson,Mid+1,r);
	tree[p].ans = tree[leftson].ans + tree[rightson].ans;
	tree[p].power = tree[leftson].power + tree[rightson].power;
	
}
inline void push_down(int p) {
	
	if(tree[p].tag) {
		tree[leftson].power += 2 * tree[p].tag * tree[leftson].ans + (tree[leftson].r-tree[leftson].l+1) * tree[p].tag * tree[p].tag;
		tree[rightson].power += 2 * tree[p].tag * tree[rightson].ans + (tree[rightson].r-tree[rightson].l+1) * tree[p].tag * tree[p].tag;
		tree[leftson].ans += tree[p].tag * (tree[leftson].r - tree[leftson].l + 1);
		tree[rightson].ans += tree[p].tag * (tree[rightson].r - tree[rightson].l + 1);
		tree[leftson].tag += tree[p].tag;
		tree[rightson].tag += tree[p].tag;
		tree[p].tag = 0;
	}
	
}
inline void update(int p,int nl,int nr,double k) {
	
	if(nl <= tree[p].l && tree[p].r <= nr) {
		tree[p].tag += k;
		tree[p].power += 2 * k * tree[p].ans+(tree[p].r-tree[p].l+1)*k*k;
		tree[p].ans += (tree[p].r - tree[p].l + 1) * k;
		return;
	} push_down(p);
	if(nl <= mid) update(leftson,nl,nr,k);
	if(nr > mid) update(rightson,nl,nr,k);
	tree[p].ans = tree[leftson].ans + tree[rightson].ans;
	tree[p].power = tree[leftson].power + tree[rightson].power;
	
}
inline double query_sum(int p,int nl,int nr) {
	
	if(nl <= tree[p].l && tree[p].r <= nr) return tree[p].ans;
	push_down(p);
	double res = 0;
	if(nl <= mid) res += query_sum(leftson,nl,nr);
	if(nr > mid) res += query_sum(rightson,nl,nr);
	return res;
	
}
inline double query_power(int p,int nl,int nr) {
	
	if(tree[p].l <= nl && nr <= tree[p].r) return tree[p].power;
	push_down(p);
	double res = 0;
	if(nl <= mid) res += query_power(leftson,nl,nr);
	if(nr > mid) res += query_power(rightson,nl,nr);
	return res;
	
}
int main() {
	
	scanf("%d%d",&n,&m);
	for(int i = 1;i <= n;i++) scanf("%lf",&arr[i]);
	build(1,1,n);
	for(int i = 1;i <= m;i++) {
		int opt,l,r;
		scanf("%d%d%d",&opt,&l,&r);
		if(opt == 1) {
			double k;
			scanf("%lf",&k);
			update(1,l,r,k);
		} else {
			double pjs = query_sum(1,l,r)/(r-l+1);
			if(opt == 2) printf("%.4lf\n",pjs);
			else {
				double ans = query_power(1,l,r)/(r-l+1);
				double k = ans - pjs * pjs;
				printf("%.4lf\n",ans);
			}
		}
	}
	
}