见down函数
#include <bits/stdc++.h>
using namespace std;
using db = double;
const int maxN = 1e5 + 7;
const db eps = 1e-7;
struct Tree {
int l, r;
db x2, sum;
db tg;
} t[maxN << 2];
#define ls (p << 1)
#define rs (p << 1 | 1)
void upd(int p) {
t[p].sum = t[ls].sum + t[rs].sum;
t[p].x2 = t[ls].x2 + t[rs].x2;
}
void build(int L, int R, int p, db B[]) {
t[p].l = L; t[p].r = R;
if (L == R) {
t[p].x2 = B[L] * B[L];
t[p].sum = B[L];
} else {
int mid = (L + R) >> 1;
build(L, mid, ls, B);
build(mid + 1, R, rs, B);
upd(p);
}
}
void make(Tree &tmp, db lz) {
int len = tmp.r - tmp.l + 1;
tmp.x2 += lz * lz * len + 2 * lz * tmp.sum;
tmp.sum += lz * len;
tmp.tg += lz;
}
void down(int p) {
if (t[p].tg == 0) return;//这样能过
//if (t[p].tg < eps) return; //这样不能过
make(t[ls], t[p].tg);
make(t[rs], t[p].tg);
t[p].tg = 0;
}
void C(int L, int R, int p, db v) {
if (L <= t[p].l && t[p].r <= R) make(t[p], v);
else {
down(p);
int mid = (t[p].l + t[p].r) >> 1;
if (L <= mid) C(L, R, ls, v);
if (R > mid) C(L, R, rs, v);
upd(p);
}
}
db query(int L, int R, int p) {
if (L <= t[p].l && t[p].r <= R) return t[p].sum;
down(p);
int mid = (t[p].l + t[p].r) >> 1;
db res = 0;
if (L <= mid) res += query(L, R, ls);
if (R > mid) res += query(L, R, rs);
return res;
}
db ask(int L, int R, int p) {
if (L <= t[p].l && t[p].r <= R) return t[p].x2;
down(p);
int mid = (t[p].l + t[p].r) >> 1;
db res = 0;
if (L <= mid) res += ask(L, R, ls);
if (R > mid) res += ask(L, R, rs);
return res;
}
int n, m;
db a[maxN];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
build(1, n, 1, a);
while (m--) {
int op, x, y;
cin >> op >> x >> y;
int len = y - x + 1;
if (op == 1) {
db k;
cin >> k;
C(x, y, 1, k);
}
if (op == 2) {
db res = query(x, y, 1) / len;
printf("%.4lf\n", res);
}
if (op == 3) {
db res = 0;
res += ask(x, y, 1);
db tmp = query(x, y, 1) / len;
res += tmp * tmp * len;
res -= 2 * tmp * query(x, y, 1);
res /= len;
printf("%.4lf\n", res);
}
}
}