萌新求助线段树死活过不了
  • 板块P1471 方差
  • 楼主dudujerry
  • 当前回复3
  • 已保存回复3
  • 发布时间2020/11/20 19:03
  • 上次更新2023/11/5 07:40:07
查看原帖
萌新求助线段树死活过不了
36502
dudujerry楼主2020/11/20 19:03

我推得方差公式是 Σ(i=1,n)ai^2 + 2 * average(a) * sum(a) + n * average(a)^2

按照这个式子写了下线段树维护区间平方和,输出的时候按照上述公式减去Σ外面的项,得到结果,过样例了,但是就是WA,看了题解,也没明白错在哪,求大佬指教

#include <cstdio>
#include <cmath>
#include <cstring>

const int MAXN = 100005;

struct TREE{
	double w,f;
	double d;
}tree[MAXN*4];

int n,m;
double num[MAXN];

void build(int k,int l,int r){
	if(l == r){
		tree[k].w = num[l];
		tree[k].d = num[l]*num[l];
		return;
	}
	int mid = (l+r)>>1;
	build(k<<1,l,mid);
	build((k<<1)+1,mid+1,r);
	tree[k].w = tree[k<<1].w + tree[(k<<1)+1].w;
	tree[k].d = tree[k<<1].d + tree[(k<<1)+1].d;
}

void ad(int k,int l,int r,double v){
	tree[k].d += 2*v*tree[k].w + (r-l+1)*v*v;
	tree[k].w += (r-l+1)*v;
	tree[k].f += v;
}

void pushdown(int k,int l,int r){
	if(tree[k].f == 0) return;
	int mid = (l+r)>>1;
	ad(k<<1,l,mid,tree[k].f);
	ad((k<<1)+1,mid+1,r,tree[k].f);
	tree[k].f = 0;
}

int gl,gr;
double ret;
void search_average(int k,int l,int r){
	if(l > gr || r < gl) return;
	if(l >= gl && r <= gr){
		ret += tree[k].w;
		return;
	}
	pushdown(k,l,r);
	int mid = (l+r)>>1;
	search_average(k<<1,l,mid);
	search_average((k<<1)+1,mid+1,r);
}

void search_variance(int k,int l,int r){
	if(l > gr || r < gl) return;
	if(l >= gl && r <= gr){
		ret += tree[k].d;
		return;
	}
	pushdown(k,l,r);
	int mid = (l+r)>>1;
	search_average(k<<1,l,mid);
	search_average((k<<1)+1,mid+1,r);
}

double gv;

void alter_section(int k,int l,int r){
	if(l > gr || r < gl) return;
	if(l >= gl && r <= gr){
		ad(k,l,r,gv);
		return;
	}
	//pushdown(k,l,r);
	int mid = (l+r)>>1;
	alter_section(k<<1,l,mid);
	alter_section((k<<1)+1,mid+1,r);
	tree[k].w = tree[k<<1].w + tree[(k<<1)+1].w;
	tree[k].d = tree[k<<1].d + tree[(k<<1)+1].d;
}

int main()

{
	scanf("%d%d",&n,&m);
	
	for(int i = 1; i <= n ; i++){
		scanf("%lf",&num[i]);
	}
	
	build(1,1,n);
	
	for(int i = 1; i <= m; i ++){
		int t;
		scanf("%d",&t);
		if(t == 1){
			scanf("%d%d%lf",&gl,&gr,&gv);
			alter_section(1,1,n);
		}
		else if(t == 2){
			scanf("%d%d",&gl,&gr);
			ret = 0;
			search_average(1,1,n);
			printf("%.4lf\n",ret/(gr-gl+1));
		}
		else if(t == 3){
			scanf("%d%d",&gl,&gr);
			ret = 0;
			search_average(1,1,n);
			double sum = ret;
			double aver = ret/(gr-gl+1);
			ret = 0;
			search_variance(1,1,n);
			//printf("a^2+b^2+c^2=%.4f\n",ret);
			printf("%.4lf\n",(ret-2*aver*sum+(gr-gl+1)*aver*aver)/(gr-gl+1));
		}
	}
	
	
	return 0;
}
2020/11/20 19:03
加载中...