本地可过提交 RE 求调
  • 板块P1471 方差
  • 楼主B612Dusk
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/11/6 08:14
  • 上次更新2023/11/6 08:15:47
查看原帖
本地可过提交 RE 求调
756660
B612Dusk楼主2023/11/6 08:14

额,本地可过可能不敢说,至少第一个测试点事对的~~(我也只能看到第一个测试点了,因为 RE 了)~~

#include <bits/stdc++.h>
const int N = 1000010;
#define int long long
const int mod = 998244353;
const int inf = 0x7fffffffffffff;

using namespace std;

int n, Q;
double a[N];

inline int read()
{
	int t;
	scanf("%lld", &t);
	return t;
}

inline double double_read()
{
	double t;
	scanf("%lf", &t);
	return t;
}

struct Seg{
	int l, r;
	double sum, fms, tag;
	#define l(p)	tree[p].l
	#define r(p)	tree[p].r
	#define sum(p)	tree[p].sum
	#define fms(p)	tree[p].fms
	#define tag(p)	tree[p].tag
}tree[N << 2];

void build(int p, int l, int r)
{
	l(p) = l, r(p) = r;
	if(l == r)
	{
		sum(p) = a[l];
		fms(p) = a[l] * a[l];
		return;
	}
	int mid = l + r >> 1;
	build(p << 1, l, mid);
	build(p << 1 | 1, mid + 1, r);
	sum(p) = sum(p << 1) + sum(p << 1 | 1);
	fms(p) = fms(p << 1) + fms(p << 1 | 1);
}

inline void Spread(int p)
{
	if(tag(p))
	{
		fms(p << 1) += tag(p) * 2 * sum(p << 1) + tag(p) * tag(p) * (r(p << 1) - l(p << 1) + 1);
		fms(p << 1 | 1) += tag(p) * 2 * sum(p << 1 | 1) + tag(p) * tag(p) * (r(p << 1 | 1) - l(p << 1 | 1) + 1);
		
		sum(p << 1) += (r(p << 1) - l(p << 1) + 1) * tag(p);
		sum(p << 1 | 1) += (r(p << 1 | 1) - l(p << 1 | 1) + 1) * tag(p);
		
		tag(p << 1) += tag(p);
		tag(p << 1 | 1) += tag(p);
		
		tag(p) = 0;
	}
}

void mtf(int p, int l, int r, double c)
{
	if(l(p) >= l and r(p) <= r)
	{
		tag(p) += c;
		fms(p) += 2 * c * sum(p) + c * c * (r(p) - l(p) + 1);
		sum(p) += (r(p) - l(p) + 1) * c;
		return;
	}
	Spread(p);
	int mid = l(p) + r(p) >> 1;
	if(l <= mid)	mtf(p << 1, l, r, c);
	if(r > mid)		mtf(p << 1 | 1, l, r, c);
	sum(p) = sum(p << 1) + sum(p << 1 | 1);
	fms(p) = fms(p << 1) + fms(p << 1 | 1);
}

double qry(int p, int l, int r, bool op)
{
	if(l(p) >= l and r(p) <= r)	return op ? fms(p) : sum(p);
	Spread(p);
	int mid = l(p) + r(p) >> 1;
	double Val = 0.0;
	if(l <= mid)	Val += qry(p << 1, l, r, op);
	if(r > mid)		Val += qry(p << 1 | 1, l, r, op);
	return Val;
}

signed main()
{	
	freopen("data.in", "r", stdin);
	n = read(), Q = read();
	for(int i = 1;i <= n;i = -~i)	a[i] = double_read();
	build(1, 1, n);
	
	while(Q --)
	{
		int op = read();
		if(op == 1)
		{
			int l = read(), r = read();
			double c = double_read();
			mtf(1, l, r, c);
		}
		else if(op == 2)
		{
			int l = read(), r = read();
			double Sum = qry(1, l, r, 0); // 取出这段区间的和
			printf("%.4lf\n", Sum / (1.0 * (r - l + 1)));
		}
		else
		{
			int l = read(), r = read();
			double Fms = qry(1, l, r, 1);
			double Sum = qry(1, l, r, 0);
			double xba = Sum / (1.0 * (r - l + 1)); // 平均数
			
			printf("%.4lf\n", (Fms - xba * 2 * Sum + (r - l + 1) * xba * xba) / (1.0 * (r - l + 1)));
		}
	}
	return 0;
}
2023/11/6 08:14
加载中...