40分线段树求助,WA全部因为方差输出了负值
查看原帖
40分线段树求助,WA全部因为方差输出了负值
352426
就决定是你辣楼主2022/8/15 16:10

pushdown和change可能出了点问题TAT

#include<iostream>
#include<cstdio>
using namespace std;
struct node{
	int l,r;
	double sum,sum2,lazy;
}d[400005];
double a[100005];
void build(int p,int l,int r){
	d[p].l=l,d[p].r=r;
	if(l==r){
		d[p].sum=a[l];
		d[p].sum2=a[l]*a[l];
		return ;
	}
	int mid=l+r>>1;
	build(p*2+1,mid+1,r);
	build(p*2,l,mid);
	d[p].sum=d[p*2].sum+d[p*2+1].sum;
	d[p].sum2=d[p*2].sum2+d[p*2+1].sum2;
}
void pushdown(int p){
	if(!d[p].lazy)return;
	else {
		double k=d[p].lazy;
		d[p*2].sum2+=2*k*d[p*2].sum+(d[p*2].r-d[p*2].l+1)*k*k;
		d[p*2+1].sum2+=2*k*d[p*2+1].sum+(d[p*2+1].r-d[p*2+1].l+1)*k*k;
		d[p*2].sum+=(d[p*2].r-d[p*2].l+1)*k;
		d[p*2+1].sum+=(d[p*2+1].r-d[p*2+1].l+1)*k;
		d[p*2].lazy+=k,d[p*2+1].lazy+=k;
		d[p].lazy=0;
	}
}
void change(int p,int l,int r,double k){
	//cout<<l<<" "<<r<<endl;
	if(d[p].l>=l&&d[p].r<=r){
	//	cout<<p<<endl;
		d[p].sum2+=2*k*d[p].sum+(d[p].r-d[p].l+1)*k*k;
		d[p].sum+=(d[p].r-d[p].l+1)*k;
		d[p].lazy+=k;
		return ;
	}
	pushdown(p);
	int mid=d[p].l+d[p].r>>1;
	if(mid>=l)change(p*2,l,r,k);
	if(mid<r)change(p*2+1,l,r,k);
	d[p].sum=d[p*2].sum+d[p*2+1].sum;
	d[p].sum2=d[p*2].sum2+d[p*2+1].sum2;
}

double getsum1(int p,int l,int r){
	//cout<<p<<" ";
	
	if(d[p].l>=l&&d[p].r<=r){
		
		return d[p].sum;
	}
	pushdown(p);
	int mid=(d[p].l+d[p].r)/2;
	//cout<<d[p].l<<" "<<d[p].r<<" "<<r<<" "<<mid<<endl;
	double s=0;
	if(mid<r)s+=getsum1(p*2+1,l,r);
	if(mid>=l)s+=getsum1(p*2,l,r);
	return s;
}
double getsum2(int p,int l,int r){
//	cout<<p<<" "<<d[p].sum2<<endl;
	if(d[p].l>=l&&d[p].r<=r){
		
		return d[p].sum2;
	}
	pushdown(p);
	int mid=(d[p].l+d[p].r)/2;
	double s2=0;
	if(mid<r)s2+=getsum1(p*2+1,l,r);
	if(mid>=l)s2+=getsum1(p*2,l,r);
	return s2;
}
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	build(1,1,n);
//	for(int i=1;i<=2*n;i++)cout<<d[i].sum2<<endl;
	for(int i=1;i<=m;i++){
		//for(int i=1;i<=2*n;i++)cout<<d[i].sum<<" "<<d[i].sum2<<endl; 
		 
		double b,x,y;
		double k;
		cin>>b;
		if(b==1){
			cin>>x>>y>>k;
			change(1,x,y,k);
		}
		else if(b==2){
			cin>>x>>y;
			double cnt=double(getsum1(1,x,y));
			double ans=double(double(cnt)/double(y-x+1));
			
			printf("%.4lf\n",ans);
			
		}
		else if(b==3){
			cin>>x>>y;
			double ans=double(getsum1(1,x,y))/double(y-x+1)*double(getsum1(1,x,y))/double(y-x+1);
			double ans2=double(getsum2(1,x,y))/double(y-x+1)-ans;
		//	cout<<getsum2(1,x,y)<<endl;
		printf("%.4lf\n",ans2);
		}
	}
}
2022/8/15 16:10
加载中...