//方差
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using db = double;
#define rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define pre(i, a, b) for(int i = (a); i >= (b); --i)
#define il inline
#define mem(a, b) memset(a, b, sizeof a)
#define debug(x) cerr << #x << '=' << x << ' '
#define FILE(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
const int N = 1e5 + 10;
int n, m;
db a[N];
template<typename T, const int N>
class segment_tree {
public:
#define mid ((l + r) >> 1)
#define ls (p << 1)
#define rs (p << 1 | 1)
struct node {
T sum, ping;
T add_tag;
il node(): sum(0), ping(0), add_tag(0) {}
il node operator + (const node &b) const {
node res;
res.sum = sum + b.sum;
res.ping = ping + b.ping;
res.add_tag = 0;
return res;
}
} t[N << 2];
private:
il void Apply_add(int p, int l, int r, T k) {
t[p].add_tag += k;
t[p].ping += (2.0 * k * t[p].sum + (r - l + 1) * k * k);
t[p].sum += (k * (r - l + 1));
}
il void Push_down(int p, int l, int r) {
if(t[p].add_tag != 0)
{
Apply_add(ls, l, mid, t[p].add_tag);
Apply_add(rs, mid + 1, r, t[p].add_tag);
t[p].add_tag = 0;
}
}
public:
il void build_tree(int p, int l, int r) {
if(l == r)
{
t[p].sum = a[l];
t[p].ping = a[l] * a[l];
t[p].add_tag = 0;
return;
}
build_tree(ls, l, mid);
build_tree(rs, mid + 1, r);
t[p] = t[ls] + t[rs];
}
il void modify(int p, int l, int r, int x, int y, T k) {
if(r < x || y < l) return;
if(x <= l && r <= y)
{
Apply_add(p, l, r, k);
return;
}
Push_down(p, l, r);
if(x <= mid) modify(ls, l, mid, x, y, k);
if(y > mid) modify(rs, mid + 1, r, x, y, k);
t[p] = t[ls] + t[rs];
}
il node query(int p, int l, int r, int x, int y) {
if(x <= l && r <= y)
return t[p];
Push_down(p, l, r);
if(y <= mid) return query(ls, l, mid, x, y);
if(x > mid) return query(rs, mid + 1, r, x, y);
return query(ls, l, mid, x, y) + query(rs, mid + 1, r, x, y);
}
};
segment_tree<db, N> T;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0), std::cout.tie(0);
cin >> n >> m;
rep(i, 1, n) cin >> a[i];
T.build_tree(1, 1, n);
while(m--)
{
int opt, x, y, k;
cin >> opt >> x >> y;
if(opt == 1)
{
cin >> k;
T.modify(1, 1, n, x, y, k);
}
if(opt == 2)
{
cout << fixed << setprecision(4) << 1.0 * T.query(1, 1, n, x, y).sum / (y - x + 1) << '\n';
}
if(opt == 3)
{
segment_tree<db, N>::node tmp = T.query(1, 1, n, x, y);
db sum = tmp.sum;
db ping = tmp.ping;
db average = sum / (y - x + 1);
cout << fixed << setprecision(4) << 1.0 * ping / (y - x + 1) - 1.0 * average * average << '\n';
}
}
return 0;
}
0pts 全WA To short on line