关于某数学教材上的分层方差合并
  • 板块P1471 方差
  • 楼主zimujun
  • 当前回复3
  • 已保存回复3
  • 发布时间2020/12/10 22:05
  • 上次更新2023/11/5 06:18:22
查看原帖
关于某数学教材上的分层方差合并
118196
zimujun楼主2020/12/10 22:05

RT

没用题解区给的大部分做法,而是用的某教材上的分层方差求总方差的 将两组数据方差合并 的方法。

交了一发,平均值没出错

求助

#include <bits/stdc++.h>
#define LF double
#define ls t << 1
#define rs t << 1 | 1

const int Maxn = 1e5 + 5;

namespace Basic {
	template <typename Temp>
	inline void read(Temp & res) {
		Temp fh = 1; res = 0; char ch = getchar();
		for(; !isdigit(ch); ch = getchar()) if(ch == '-') fh = -1;
		for(; isdigit(ch); ch = getchar()) res = (res << 3) + (res << 1) + (ch ^ '0');
		res = res * fh;
	}
	template <typename Temp>
	inline void readf(Temp & res) {
		Temp fh = 1; res = 0; char ch = getchar();
		for(; !isdigit(ch); ch = getchar()) if(ch == '-') fh = -1;
		for(; isdigit(ch); ch = getchar()) res = res * 10 + (ch ^ '0');
		if(ch != '.') {res = res * fh; return;}
		ch = getchar(); for(Temp base = 0.1; isdigit(ch); ch = getchar(), base = base / 10) res = res + (ch ^ '0') * base;
		res = res * fh; 
	}
	template <typename Temp> inline void Checkmax(Temp & num, Temp comp) {if(comp > num) num = comp;}
	template <typename Temp> inline void Checkmin(Temp & num, Temp comp) {if(comp < num) num = comp;}
}
using namespace Basic;
using namespace std;

struct Seg {
	LF average;
	LF data;
	LF tag;
	LF siz;
	Seg() {average = data = tag = 0;}
} a[Maxn << 2];

LF num[Maxn];

int n, m, opt, x, y;
LF k;

inline Seg merge(Seg L, Seg R) {
	Seg res; LF P = L.siz * R.siz / (L.siz + R.siz);
	res.average = (L.siz * L.average + R.siz * R.average) / (L.siz + R.siz);
	res.data = (L.data + R.data + P * (L.average - R.average) * (L.average - R.average)) / (L.siz + R.siz);
	res.siz = L.siz + R.siz;
	return res;
}

inline void pushup(int t) {
	a[t] = merge(a[ls], a[rs]);
}

inline void pushdown(int t) {
	a[ls].average += a[t].tag; a[rs].average += a[t].tag;
	a[ls].tag += a[t].tag; a[rs].tag += a[t].tag;
	a[t].tag = 0;
}

void build(int l, int r, int t) {
	if(l == r) {
		a[t].data = 0;
		a[t].average = num[l];
		a[t].tag = 0;
		a[t].siz = 1;
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, ls);
	build(mid + 1, r, rs);
	pushup(t);
}

void modify(int lf, int rt, LF add, int l, int r, int t) {
	if((lf <= l) && (r <= rt)) {
		a[t].average += add;
		a[t].tag += add;
		return;
	}
	pushdown(t);
	int mid = (l + r) >> 1;
	if(lf <= mid) modify(lf, rt, add, l, mid, ls);
	if(rt > mid) modify(lf, rt, add, mid + 1, r, rs);
	pushup(t);
}

Seg query(int lf, int rt, int l, int r, int t) {
	if((lf <= l) && (r <= rt)) return a[t];
	int mid = (l + r) >> 1; pushdown(t);
	if(rt <= mid) return query(lf, rt, l, mid, ls);
	if(lf > mid) return query(lf, rt, mid + 1, r, rs);
	return merge(query(lf, rt, l, mid, ls), query(lf, rt, mid + 1, r, rs));
}

int main() {
	cin >> n >> m;
	for(register int i = 1; i <= n; ++i) cin >> num[i];
	build(1, n, 1);
	while(m--) {
		cin >> opt;
		if(opt == 1) {
			cin >> x >> y >> k;
			modify(x, y, k, 1, n, 1);
		} else if(opt == 2) {
			cin >> x >> y;
			printf("%.4lf\n", query(x, y, 1, n, 1).average);
		} else {
			cin >> x >> y;
			printf("%.4lf\n", query(x, y, 1, n, 1).data);
		}
	}
	return 0;
} 
2020/12/10 22:05
加载中...