线段树0分求调!玄关!样例过了!
  • 板块P1471 方差
  • 楼主_Ayanami_Rei_
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/11/21 19:48
  • 上次更新2023/11/21 20:21:27
查看原帖
线段树0分求调!玄关!样例过了!
596448
_Ayanami_Rei_楼主2023/11/21 19:48
#include <iostream>
#include <cstdio>
using namespace std;
#define ls(p) (p << 1)
#define rs(p) ((p << 1) | 1)

int n, m, cnt = 0;
double t[4000020], tag[4000020], s[4000020];

void push_up (int p) {
	t[p] = t[ls(p)] + t[rs(p)];
	s[p] = s[ls(p)] + s[rs(p)];
}

void add_tag (int p, int pl, int pr, double k) {
	s[p] += k * k * (pr - pl + 1) + 2 * k * t[p];
	t[p] += k;
	tag[p] += k;
}

void push_down (int p, int pl, int pr) {
	if (tag[p] != 0) {
		add_tag(ls(p), pl, pr, tag[p]);
		add_tag(rs(p), pl, pr, tag[p]);
		tag[p] = 0;
	}
}

void Build (int p, int pl, int pr) {
	tag[p] = 0.0;
	if (pl == pr) {
		scanf ("%lf", t + p);
		s[p] = t[p] * t[p];
		return ;
	}
	int mid = (pl + pr) / 2;
	Build (ls(p), pl, mid);
	Build (rs(p), mid + 1, pr);
	push_up(p);
}

void Update (int p, int pl, int pr, int l, int r, double k) {
	if (l <= pl && pr <= r) {
		add_tag (p, pl, pr, k);
		return ;
	}
	int mid = (pl + pr) / 2;
	push_down(p, pl, pr);
	if (mid >= l) {
		Update (ls(p), pl, mid, l, r, k);
	}
	if (mid < r) {
		Update (rs(p), mid + 1, pr, l, r, k);
	}
	push_up(p);
}

double get_ans (int op, int p, int pl, int pr, int l, int r) {
	if (l <= pl && pr <= r) {
		if (op == 1)
			return t[p];
		return s[p];
	}
	push_down (p, pl, pr);
	int mid = (pl + pr) / 2;
	double s = 0.0;
	if (mid >= l) {
		s += get_ans(op, ls(p), pl, mid, l, r);
	}
	if (mid < r) {
		s += get_ans(op, rs(p), mid + 1, pr, l, r);
	}
	return s;
}

int main () {
	scanf ("%d %d", &n, &m);
	Build (1, 1, n);
	while (m--) {
		int op, x, y;
		scanf ("%d %d %d", &op, &x, &y);
		if (op == 1) {
			double k;
			scanf ("%lf", &k);
			Update (1, 1, n, x, y, k);
		}
		else if (op == 2) {
			printf("%.4f\n", get_ans (1, 1, 1, n, x, y) * 1.0 / (y - x + 1));
		}
		else {
			double num = get_ans (1, 1, 1, n, x, y), a = num * 1.0 / (y - x + 1);
			double sum = get_ans (0, 1, 1, n, x, y) + (y - x + 1) * a * a - 2 * a * num;
			printf("%.4f\n", sum * 1.0 / (y - x + 1));
		}
	}
	return 0;
}

2023/11/21 19:48
加载中...