P1471 方差

题目

luogu

思路

[frac{1}{n}*sum_{1}^{n}( a_{i}-A)^{2} ]

[frac{1}{n}*sum_{1}^{n}( a_{i}^2-2*A*a_{i}+A^2) ]

[frac{1}{n}*(sum_{1}^{n} a_{i}^{2}-2*Asum_{1}^{n} a_{i})+A^{2} ]

那就是维护区间和和区间平方和平方和很好维护吧

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#define ls rt<<1
#define rs rt<<1|1
#define ll long long
using namespace std;
const int maxn = 1e5 + 7;
struct node  {
	int l, r;
	double tot, lazy, pfh;
} e[maxn << 2];
int n, m;
double ans1, ans2;
void pushup(int rt)  {
	e[rt].tot = e[ls].tot + e[rs].tot;
	e[rt].pfh = e[ls].pfh + e[rs].pfh;
}
void pushdown(int rt) {
	if (e[rt].lazy)
	{
		e[ls].pfh += 2 * e[rt].lazy * e[ls].tot + (e[ls].r - e[ls].l + 1) * e[rt].lazy * e[rt].lazy;
		e[rs].pfh += 2 * e[rt].lazy * e[rs].tot + (e[rs].r - e[rs].l + 1) * e[rt].lazy * e[rt].lazy;
		e[ls].tot += (e[ls].r - e[ls].l + 1) * e[rt].lazy;
		e[rs].tot += (e[rs].r - e[rs].l + 1) * e[rt].lazy;
		e[ls].lazy += e[rt].lazy;
		e[rs].lazy += e[rt].lazy;
		e[rt].lazy = 0;
	}
}
void build(int l, int r, int rt) {
	e[rt].l = l, e[rt].r = r;
	if (l == r) {
		scanf("%lf", &e[rt].tot);
		e[rt].pfh = e[rt].tot * e[rt].tot;
		return;
	}
	int m = (l + r) >> 1;
	build(l, m, ls);
	build(m + 1, r, rs);
	pushup(rt);
}
void modify(int L, int R, double x, int rt) {
	if (L <= e[rt].l && e[rt].r <= R) {
		e[rt].pfh += 2 * x * e[rt].tot + x * x * (e[rt].r - e[rt].l + 1);
		e[rt].tot += (e[rt].r - e[rt].l + 1) * x;
		e[rt].lazy += x;
		return;
	}
	pushdown(rt);
	int m = (e[rt].l + e[rt].r) >> 1;
	if (L <= m) modify(L, R, x, ls);
	if (R > m) modify(L, R, x, rs);
	pushup(rt);
}
void query(int L, int R, int rt) {
	if (L <= e[rt].l && e[rt].r <= R) {
		ans1 += e[rt].tot;
		ans2 += e[rt].pfh;
		return;
	}
	pushdown(rt);
	int m = (e[rt].l + e[rt].r) >> 1;
	if (L <= m) query(L, R, ls);
	if (R > m) query(L, R, rs);
	pushup(rt);
}

int main()  {
	scanf("%d%d", &n, &m);
	build(1, n, 1);
	while (m--) {
		int opt, a, b;
		double x;
		scanf("%d", &opt);
		if (opt == 1)  {
			scanf("%d%d%lf", &a, &b, &x);
			modify(a, b, x, 1);
		}
		if (opt == 2) {
			scanf("%d%d", &a, &b);
			ans1 = ans2 = 0;
			query(a, b, 1);
			printf("%.4lf
", ans1 / (b - a + 1));
		}
		if (opt == 3) {
			scanf("%d%d", &a, &b);
			ans1 = ans2 = 0;
			query(a, b, 1);
			double tmp = ans1 / (b - a + 1);
			printf("%.4lf
", tmp * tmp + (ans2 - 2.0 * tmp * ans1) / (b - a + 1));
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/dsrdsr/p/9881077.html