能用 double 的都用了
鬼畜输入数据
1 2 8 -2.7566713364794850E+0000
1 2 8 2.1308819339610636E+0000
1 1 6 1.5912831262685359E+0000
1 1 8 -2.7779214559122920E+0000
1 1 8 -6.5134523715823889E-0001
#include <bits/stdc++.h>
#define lson p << 1
#define rson p << 1 | 1
using namespace std;
const int N = 100005;
struct Seg {
int l, r;
double sum = 0, psum = 0, tag = 0;
#define l(p) t[p].l
#define r(p) t[p].r
#define sum(p) t[p].sum
#define psum(p) t[p].psum
#define tag(p) t[p].tag
#define len(p) (r(p) - l(p) + 1.0)
} t[N << 2];
int n, m, op, x, y;
double a[N], k;
void read(int &a, int ch = 0, int f = 1) {
while (!isdigit(ch = getchar())) if (ch == '-') f = -1;
for (a = 0; isdigit(ch); ch = getchar()) a = (a << 3) + (a << 1) + (ch ^ 48); a *= f;
}
inline void pushup(int p) {
sum(p) = sum(lson) + sum(rson);
psum(p) = psum(lson) + psum(rson);
}
inline void pushdown(int p) {
if (tag(p) != 0) {
tag(lson) += tag(p);
tag(rson) += tag(p);
psum(lson) += 2.0 * tag(p) * sum(lson) + len(lson) * tag(p) * tag(p);
psum(rson) += 2.0 * tag(p) * sum(rson) + len(rson) * tag(p) * tag(p);
sum(lson) += tag(p) * len(lson);
sum(rson) += tag(p) * len(rson);
tag(p) = 0;
}
}
void build(int p, int l, int r) {
l(p) = l, r(p) = r, tag(p) = 0;
if (l == r) {
sum(p) = a[l];
psum(p) = a[l] * a[l];
return;
}
int mid = l + r >> 1;
build(lson, l, mid);
build(rson, mid + 1, r);
pushup(p);
}
void maketag(int p, int l, int r, double k) {
if (l <= l(p) && r >= r(p)) {
tag(p) += k;
psum(p) += 2.0 * k * sum(p) + len(p) * k * k;
sum(p) += k * len(p);
return;
}
pushdown(p);
int mid = l(p) + r(p) >> 1;
if (l <= mid) maketag(lson, l, r, k);
if (r > mid) maketag(rson, l, r, k);
pushup(p);
}
Seg merge(Seg a, Seg b) {
Seg res;
res.sum = a.sum + b.sum;
res.psum = a.psum + b.psum;
return res;
}
Seg query(int p, int l, int r) {
if (l <= l(p) && r >= r(p)) return t[p];
pushdown(p);
int mid = l(p) + r(p) >> 1;
if (r <= mid) return query(lson, l, r);
if (l > mid) return query(rson, l, r);
return merge(query(lson, l, r), query(rson, l, r));
}
int main() {
read(n), read(m);
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
build(1, 1, n);
while (m--) {
read(op), read(x), read(y);
if (op == 1) {
cin >> k;
maketag(1, x, y, k);
} else if (op == 2) {
Seg res = query(1, x, y);
printf("%.4lf\n", res.sum / (y - x + 1.0));
} else {
Seg res = query(1, x, y);
printf("%.4lf\n", res.psum / (double)n - (res.sum / (y - x + 1.0)) * (res.sum / (y - x + 1.0)));
}
}
return 0;
}