40pts求调
  • 板块P1471 方差
  • 楼主suxiaozhou
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/7/4 21:23
  • 上次更新2024/7/5 09:20:08
查看原帖
40pts求调
781131
suxiaozhou楼主2024/7/4 21:23

#1、2、3、4、9、10测试点WA

找不到问题出在哪里

蒟蒻跪求路过大佬帮忙,看一下思路和代码.

思路

设一个位置原本的值为aa,增加的值为Δa\Delta a

lenlen表示区间长度,sumsum表示区间和

区间平方和 Σa2\Sigma a^2 变成 Σ(a+Δa)2\Sigma (a+\Delta a)^2

区间平方和增加值为Σ[(a+Δa)2−Σa2]\Sigma [(a+\Delta a)^2-\Sigma a^2]

展开得到:Σ(2aΔa+Δa2)\Sigma (2a\Delta a+\Delta a^2)

=2∗sum∗Δa+len∗Δa2=2*sum*\Delta a+len*\Delta a^2

代码

#include <bits/stdc++.h>
using namespace std;
#define ll double //不好的习惯,被实数要求暴击
int n, m, cmd, x, y;
ll k;
ll t[100010], tree[100010 * 4], treepow2[100010 * 4];//数组,区间和,区间平方和
ll lzy[100010 * 4];//破lazy_tag

void push_up(int pos) {
	tree[pos] = tree[pos*2] + tree[pos*2 + 1];
	treepow2[pos] = treepow2[pos*2] + treepow2[pos*2 + 1];
	return;
}

void pushdown_lazytag(int l, int r, int u) {
	int M = (l + r) / 2;
	lzy[2 * u] += lzy[u];
	treepow2[2*u]+=2*tree[2*u]*lzy[u]+(M - l+1)*lzy[u]*lzy[u];
	tree[2 * u] += (M - l+1) * lzy[u];
	
	lzy[2 * u + 1] += lzy[u];
	treepow2[2*u+1]+=2*tree[2*u+1]*lzy[u]+(r - M)*lzy[u]*lzy[u];
	tree[2 * u + 1] += (r - M) * lzy[u];
	
	lzy[u] = 0.0;
	return;
}

void build(int u, int l, int r) {
	if (l == r) {
		tree[u] = t[l];
		treepow2[u] = t[l]*t[l];
		return;
	}
	int m = (l + r) / 2;
	build(2 * u, l, m);
	build(2 * u + 1, m + 1, r);
	push_up(u);
}

void update(int u, int l, int r, int x, int y, double k) { //l,r:当前范围  x,y:目标范围 k:更改值 区间修改
	if (l >= x && y >= r) { //被包含
		treepow2[u]+=2.0*tree[u]*k+(r-l+1)*k*k;
		tree[u]+=k*(r-l+1);//************************************************
		lzy[u] += k;
	} else if ((x > r) || (y < l)) { //完全没有交集
		return;
	} else { //不完全包含,马上向下追查
		int m = (l + r) / 2;
		pushdown_lazytag(l, r,u);//*******************************************
		update(u * 2, l, m, x, y, k);
		update(u * 2 + 1, m + 1, r, x, y, k);
		push_up(u);
	}
	//DEBUG
	//cout<<"DEBUG"<<treepow2[u]<<" "<<l<<" "<<r<<endl;
	return;
}

ll query(int u, int l, int r, int x, int y) { //l,r:查询范围  x,y:目标范围  区间查询
	if (l >= x && y >= r) { //被包含
		return tree[u];
	} else if ((x > r) || (y < l)) { //完全没有交集
		return 0;
	} else { //不完全对应,向下追查
		int m = (l + r) / 2;
		pushdown_lazytag(l, r, u);
		return query(u * 2, l, m, x, y) + query(u * 2 + 1, m + 1, r, x, y);
	}
}
ll quepow2(int u, int l, int r, int x, int y) { //l,r:查询范围  x,y:目标范围  区间查询
	if (l >= x && y >= r) { //被包含
		return treepow2[u];
	} else if ((x > r) || (y < l)) { //完全没有交集
		return 0;
	} else { //不完全对应,向下追查
		int m = (l + r) / 2;
		pushdown_lazytag(l, r, u);
		return quepow2(u * 2, l, m, x, y) + quepow2(u * 2 + 1, m + 1, r, x, y);
	}
}

int main() {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> t[i];
	}
	build(1, 1, n);
	while (m--) {
		cin >> cmd;
		double k;
		if (cmd == 1) {
			cin >> x >> y >> k;
			update(1, 1, n, x, y, k);
		}
		else if (cmd==2){
			cin>>x>>y;
			double adv=1.0*query(1,1,n,x,y)/(y-x+1);
			printf("%.4f\n",adv);
		}
		else{
			cin>>x>>y;
			double adv=1.0*query(1,1,n,x,y)/(y-x+1);
			printf("%.4f\n",1.0*quepow2(1,1,n,x,y)/n-2.0*adv/n*query(1,1,n,x,y)+1.0*adv*adv);
		}
	}
	return 0;
}

谢谢!!

2024/7/4 21:23
加载中...