明天考试,心态炸了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mkp make_pair
#define pb push_back
#define PII pair<int, int>
#define PLL pair<ll, ll>
#define ls(x) ((x) << 1)
#define rs(x) ((x) << 1 | 1)
#define fi first
#define se second
const int N = 1e5 + 10;
int n, m; double a[N];
struct node {
int len; double s, sf, lz;
node operator + (const node x) const {
node y;
y.len = len + x.len;
y.s = s + x.s;
y.sf = sf + x.sf;
return y;
}
}tr[N << 2];
void pushdown(int rt) {
if(tr[rt].lz != 0) {
double va = tr[rt].lz;
tr[ls(rt)].lz += va;
tr[ls(rt)].sf += 2 * va * tr[ls(rt)].s + tr[ls(rt)].len * va * va;
tr[ls(rt)].s += va * tr[ls(rt)].len;
tr[rs(rt)].lz += va;
tr[rs(rt)].sf += 2 * va * tr[rs(rt)].s + tr[rs(rt)].len * va * va;
tr[rs(rt)].s += va * tr[rs(rt)].len;
tr[rt].lz = 0;
}
return;
}
void build(int rt, int l, int r) {
tr[rt].lz = 0;
if(l == r) {
double va = a[l];
tr[rt].len = 1;
tr[rt].s = va;
tr[rt].sf = va * va;
return;
}
pushdown(rt);
int mid = (l + r) >> 1;
build(ls(rt), l, mid);
build(rs(rt), mid + 1, r);
tr[rt] = tr[ls(rt)] + tr[rs(rt)];
return;
}
void update(int rt, int l, int r, int L, int R, double va) {
if(L <= l && r <= R) {
tr[rt].lz += va;
tr[rt].sf += 2 * va * tr[rt].s + tr[rt].len * va * va;
tr[rt].s += va * tr[rt].len;
return;
}
pushdown(rt);
int mid = (l + r) >> 1;
if(L <= mid) update(ls(rt), l, mid, L, R, va);
if(R > mid) update(rs(rt), mid + 1, r, L, R, va);
tr[rt] = tr[ls(rt)] + tr[rs(rt)];
return;
}
double query1(int rt, int l, int r, int L, int R) {
if(L <= l && r <= R)
return tr[rt].s;
pushdown(rt);
int mid = (l + r) >> 1; double ret = 0;
if(L <= mid) ret += query1(ls(rt), l, mid, L, R);
if(R > mid) ret += query1(rs(rt), mid + 1, r, L, R);
tr[rt] = tr[ls(rt)] + tr[rs(rt)];
return ret;
}
double query2(int rt, int l, int r, int L, int R) {
if(L <= l && r <= R) return tr[rt].sf;
pushdown(rt);
int mid = (l + r) >> 1; double ret = 0;
if(L <= mid) ret += query2(ls(rt), l, mid, L, R);
if(R > mid) ret += query2(rs(rt), mid + 1, r, L, R);
tr[rt] = tr[ls(rt)] + tr[rs(rt)];
return ret;
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
scanf("%lf", &a[i]);
build(1, 1, n);
while(m--) {
int op, x, y; double va; scanf("%d%d%d", &op, &x, &y);
if(op == 1) {
scanf("%lf", &va);
update(1, 1, n, x, y, va);
} else if(op == 2) printf("%.4lf\n", query1(1, 1, n, x, y) / (y - x + 1));
else {
double sum = query1(1, 1, n, x, y);
double t = sum / (y - x + 1);
printf("%.4lf\n", query2(1, 1, n, x, y) / (y - x + 1) - t * t);
}
}
return 0;
}
/*
5 5
1 5 4 2 3
2 1 4
3 1 5
1 1 1 1
1 2 2 -1
3 1 5
*/