40分求调
  • 板块P1471 方差
  • 楼主ShiRoZeTsuHL卜奎BBQ!
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/2/2 10:53
  • 上次更新2023/10/24 02:06:11
查看原帖
40分求调
678858
ShiRoZeTsuHL卜奎BBQ!楼主2023/2/2 10:53
#include <iostream>
#include <cstring>
using namespace std;

#define ls (id << 1)
#define rs (id << 1 | 1)
#define mid ((l + r) >> 1)

const int maxn = 1e5 + 5;

int n, m;

struct Tree {
	double v, tag, sq;
} t[maxn<<2];

void build(int l, int r, int id) {
	if(l == r) {
		scanf("%lf", &t[id].v);
		t[id].sq = t[id].v * t[id].v;
	}
	else {
		build(l, mid, ls); build(mid+1, r, rs);
		t[id].v = t[ls].v + t[rs].v;
		t[id].sq = t[ls].sq + t[rs].sq;
	}
}

void pushup(int l, int r, int id) {
	double k = t[id].tag;
	t[ls].sq += 2*k*t[ls].v + k*k*(mid-l+1);
	t[rs].sq += 2*k*t[rs].v + k*k*(r-mid);
	t[ls].v += k * (mid-l+1);
	t[rs].v += k * (r-mid);
	t[ls].tag += k;
	t[rs].tag += k;
	t[id].tag = 0;
}

void add(int ql, int qr, int l, int r, int id, double k) {
	if(ql <= l && r <= qr) {
		t[id].sq += 2*k*t[id].v + (r-l+1)*k*k;
		t[id].v += k*(r-l+1);
		t[id].tag += k;
		return;
	}
	if(t[id].tag) pushup(l, r, id);
	if(ql <= mid) add(ql, qr, l, mid, ls, k);
	if(mid < qr) add(ql, qr, mid+1, r, rs, k);
	t[id].v = t[ls].v + t[rs].v;
	t[id].sq = t[ls].sq + t[rs].sq;
}

double getsum(int ql, int qr, int l, int r, int id) {
	if(ql <= l && r <= qr) return t[id].v;
	if(t[id].tag) pushup(l, r, id);
	double res = 0;
	if(ql <= mid) res += getsum(ql, qr, l, mid, ls);
	if(mid < qr) res += getsum(ql, qr, mid+1, r, rs);
	return res;
}

double getsq(int ql, int qr, int l, int r, int id) {
	if(ql <= l && r <= qr) return t[id].sq;
	if(t[id].tag) pushup(l, r, id);
	double res = 0;
	if(ql <= mid) res += getsq(ql, qr, l, mid, ls);
	if(mid < qr) res += getsq(ql, qr, mid+1, r, rs);
	return res;
}

int main() {
	scanf("%d %d", &n, &m);
	build(1, n, 1);
	for(int i = 1; i <= m; i++) {
		int op, x, y;
		scanf("%d %d %d", &op, &x, &y);
		if(op == 1) {
			double k;
			scanf("%lf", &k);
			add(x, y, 1, n, 1, k);
		}
		else if(op == 2)
			printf("%.4lf\n", getsum(x, y, 1, n, 1) / (y-x+1));
		else {
			double sig = getsum(x, y, 1, n, 1);
			double bar = sig / (y-x+1);
			double sq = getsq(x, y, 1, n, 1);
			printf("%.4lf\n", 1.0 * (sq - 2*bar*sig + n*bar*bar) / n);
		}
	}
	return 0;
}
2023/2/2 10:53
加载中...