求助
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
typedef long long ll;
using namespace std;
int n, m;
double val[100005];
struct node {
int l, r;
double qwq;
double laz;
double varian;
}e[400005];
void build (int o, int l, int r) {
e[o].l = l, e[o].r = r;
if (l == r) {
e[o].qwq = val[l];
e[o].varian = (double) val[l] * val[l];
return ;
}
int mid = l + r >> 1;
build (o<<1, l, mid);
build (o<<1|1, mid+1, r);
e[o].qwq = (double) e[o<<1].qwq + (double) e[o<<1|1].qwq;
e[o].varian = (double)e[o<<1].varian + (double) e[o<<1|1].varian;
}
void update (int o) {
if (e[o].laz) {
int len = e[o].r - e[o].l + 1;
e[o<<1].laz = e[o<<1|1].laz = (double) e[o].laz;
e[o<<1].varian += (double) (e[o].laz * 2) * (double) e[o<<1].qwq + (double) (len - (len>>1)) * (double) e[o].laz * (double) e[o].laz;
e[o<<1|1].varian += (double) (e[o].laz * 2) * (double) e[o<<1|1].qwq + (double) (len>>1) * (double) e[o].laz * (double) e[o].laz;
e[o<<1].qwq += (double) e[o].laz * (double) (len - (len>>1));
e[o<<1|1].qwq += (double) e[o].laz * (double) (len>>1);
e[o].laz = 0;
}
}
void add (int o, int l, int r, double k) {
if (l <= e[o].l && e[o].r <= r) {
e[o].laz += (double) k;
e[o].varian += (double) (k*2) * (double) e[o].qwq + (double) (e[o].r - e[o].l + 1) * (double) k * (double) k;
e[o].qwq += (double) k * (double) (e[o].r - e[o].l + 1);
return ;
}
update (o);
int mid = e[o].l + e[o].r >> 1;
if (l <= mid) add (o<<1, l, r, k);
if (r > mid) add (o<<1|1, l, r, k);
e[o].qwq = (double) e[o<<1].qwq + (double) e[o<<1|1].qwq;
e[o].varian = (double) e[o<<1].varian + (double) e[o<<1|1].varian;
}
double access (int o, int l, int r) {
double ans = 0;
if (l <= e[o].l && e[o].r <= r) {
return e[o].qwq;
}
update (o);
int mid = e[o].l + e[o].r >> 1;
if (l <= mid) ans += (double) access (o<<1, l, r);
if (r > mid) ans += (double) access (o<<1|1, l, r);
return ans;
}
double query (int o, int l, int r) {
double res = 0;
if (l <= e[o].l && e[o].r <= r) {
return e[o].varian;// - (double) (tmp*2) * e[o].qwq + (double) (e[o].r - e[o].l + 1) * (double) tmp * (double) tmp;
}
update (o);
int mid = e[o].l + e[o].r >> 1;
if (l <= mid) res += (double) query (o<<1, l, r);
if (r > mid) res += (double) query (o<<1|1, l, r);
return res;
}
signed main () {
std::cin>>n>>m;
for (register int i(1); i ^ (n+1); i = -~i) std::cin>>val[i];
build (1, 1, n);
while (m--) {
int flag, x, y;
std::cin>>flag>>x>>y;
if (flag == 1) {
double k;
std::cin>>k;
add (1, x, y, k);
}
else if (flag == 2) {
printf("%.4f\n", access (1, x, y) / (y - x + 1));
}
else {
double tmp = query (1, x, y); //平方和
double cnt = access (1, x, y); //和
double tnt = cnt / (y-x+1); //平均值
tmp = tmp - 2*tnt*cnt + (y-x+1)*tnt*tnt;
printf("%.4f\n", tmp / (y - x + 1));
}
}
}