蒟蒻 10 分求助
  • 板块P1471 方差
  • 楼主MurataHimeko
  • 当前回复1
  • 已保存回复1
  • 发布时间2021/2/26 10:25
  • 上次更新2023/11/5 02:41:27
查看原帖
蒟蒻 10 分求助
450290
MurataHimeko楼主2021/2/26 10:25

求助

#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));
		}
	}
}
2021/2/26 10:25
加载中...