90分WA求助 很板的线段树
  • 板块P1471 方差
  • 楼主_Felix
  • 当前回复1
  • 已保存回复1
  • 发布时间2021/11/19 21:01
  • 上次更新2023/11/4 00:05:58
查看原帖
90分WA求助 很板的线段树
106738
_Felix楼主2021/11/19 21:01

明天考试,心态炸了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mkp make_pair
#define pb push_back
#define PII pair<int, int>
#define PLL pair<ll, ll>
#define ls(x) ((x) << 1)
#define rs(x) ((x) << 1 | 1)
#define fi first
#define se second
const int N = 1e5 + 10;
int n, m; double a[N];
struct node {
	int len; double s, sf, lz;
	node operator + (const node x) const {
		node y;
		y.len = len + x.len;
		y.s = s + x.s;
		y.sf = sf + x.sf;
		return y;
	}
}tr[N << 2];
void pushdown(int rt) {
	if(tr[rt].lz != 0) {
		double va = tr[rt].lz;
		tr[ls(rt)].lz += va;
		tr[ls(rt)].sf += 2 * va * tr[ls(rt)].s + tr[ls(rt)].len * va * va;
		tr[ls(rt)].s += va * tr[ls(rt)].len;
		
		tr[rs(rt)].lz += va;
		tr[rs(rt)].sf += 2 * va * tr[rs(rt)].s + tr[rs(rt)].len * va * va;
		tr[rs(rt)].s += va * tr[rs(rt)].len;
		
		tr[rt].lz = 0;
	}
	return;
}
void build(int rt, int l, int r) {
	tr[rt].lz = 0;
	if(l == r) {
		double va = a[l];
		tr[rt].len = 1;
		tr[rt].s = va;
		tr[rt].sf = va * va;
		return;
	}
	pushdown(rt);
	int mid = (l + r) >> 1;
	build(ls(rt), l, mid);
	build(rs(rt), mid + 1, r);
	tr[rt] = tr[ls(rt)] + tr[rs(rt)];
	return;
}
void update(int rt, int l, int r, int L, int R, double va) {
	if(L <= l && r <= R) {
		tr[rt].lz += va;
		tr[rt].sf += 2 * va * tr[rt].s + tr[rt].len * va * va;
		tr[rt].s += va * tr[rt].len;
		return;
	}
	pushdown(rt);
	int mid = (l + r) >> 1;
	if(L <= mid) update(ls(rt), l, mid, L, R, va);
	if(R > mid) update(rs(rt), mid + 1, r, L, R, va);
	tr[rt] = tr[ls(rt)] + tr[rs(rt)];
	return;
}
double query1(int rt, int l, int r, int L, int R) {
	if(L <= l && r <= R)
		return tr[rt].s;
	pushdown(rt);
	int mid = (l + r) >> 1; double ret = 0;
	if(L <= mid) ret += query1(ls(rt), l, mid, L, R);
	if(R > mid) ret += query1(rs(rt), mid + 1, r, L, R);
	tr[rt] = tr[ls(rt)] + tr[rs(rt)];
	return ret;
}
double query2(int rt, int l, int r, int L, int R) {
	if(L <= l && r <= R) return tr[rt].sf;
	pushdown(rt);
	int mid = (l + r) >> 1; double ret = 0;
	if(L <= mid) ret += query2(ls(rt), l, mid, L, R);
	if(R > mid) ret += query2(rs(rt), mid + 1, r, L, R);
	tr[rt] = tr[ls(rt)] + tr[rs(rt)];
	return ret;
}
int main(){
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; i++)
		scanf("%lf", &a[i]);
	build(1, 1, n);
	while(m--) {
		int op, x, y; double va; scanf("%d%d%d", &op, &x, &y);
		if(op == 1) {
			scanf("%lf", &va);
			update(1, 1, n, x, y, va);
		} else if(op == 2) printf("%.4lf\n", query1(1, 1, n, x, y) / (y - x + 1));
		else {
			double sum = query1(1, 1, n, x, y);
			double t = sum / (y - x + 1);
			printf("%.4lf\n", query2(1, 1, n, x, y) / (y - x + 1) - t * t);
		}
	}
	return 0;
}
/*
5 5
1 5 4 2 3
2 1 4
3 1 5
1 1 1 1
1 2 2 -1
3 1 5
*/
2021/11/19 21:01
加载中...