线段树做法,40pts,求方差时为负数,已经在区间长计算时强转double
  • 板块P1471 方差
  • 楼主zhangqz
  • 当前回复5
  • 已保存回复5
  • 发布时间2023/8/3 00:47
  • 上次更新2023/11/3 06:14:35
查看原帖
线段树做法,40pts,求方差时为负数,已经在区间长计算时强转double
194236
zhangqz楼主2023/8/3 00:47

代码

#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e5+1;
struct node{
	int l,r;double sum,tag,sum2;
}tre[N*4];
double a[N];int n,m;
int ls(int x){return x<<1;}
int rs(int x){return x<<1|1;}
void ps(int x){
	tre[x].sum=tre[rs(x)].sum+tre[ls(x)].sum;
	tre[x].sum2=tre[rs(x)].sum2+tre[ls(x)].sum2;
}
void bui(int x){
	if(x==1){tre[x].l=1;tre[x].r=n;}
	if(tre[x].l==tre[x].r){
		tre[x].sum=a[tre[x].l];
		tre[x].sum2=tre[x].sum*tre[x].sum;
		return ;
	}
	int mid=(tre[x].l+tre[x].r)>>1;
	tre[ls(x)].l=tre[x].l;
	tre[ls(x)].r=mid;
	tre[rs(x)].l=mid+1;
	tre[rs(x)].r=tre[x].r;
	bui(ls(x));
	bui(rs(x));
	ps(x);
}
void f(int x,double k){
	tre[x].sum2+=k*k*(1.0*(tre[x].r-tre[x].l+1))+tre[x].sum*2.0*k;
	tre[x].sum+=k*(1.0*(tre[x].r-tre[x].l+1));
	tre[x].tag+=k;
}
void pd(int x){
	f(ls(x),tre[x].tag);
	f(rs(x),tre[x].tag);
	tre[x].tag =0;
}
void ch(int ll,int rr,int x,double k){
	if(ll<=tre[x].l&&tre[x].r<=rr){f(x,k);return;}
	int mid=(tre[x].l+tre[x].r)>>1;
	pd(x);
	if(mid>=ll) ch(ll,rr,ls(x),k);
	if(mid+1<=rr) ch(ll,rr,rs(x),k);
	ps(x);
}
double qs(int ll,int rr,int x){
	double ans=0;
	if(ll<=tre[x].l&&tre[x].r<=rr){return tre[x].sum;}
	int mid=(tre[x].l+tre[x].r)>>1;
	pd(x);
	if(mid>=ll) ans+=qs(ll,rr,ls(x));
	if(mid+1<=rr) ans+=qs(ll,rr,rs(x));
	return ans;
}
double qs2(int ll,int rr,int x){
	double ans=0;
	if(ll<=tre[x].l&&tre[x].r<=rr){return tre[x].sum2;}
	int mid=(tre[x].l+tre[x].r)>>1;
	pd(x);
	if(mid>=ll) ans+=qs(ll,rr,ls(x));
	if(mid+1<=rr) ans+=qs(ll,rr,rs(x));
	return ans;
}
int main(){
	double ansc,ansp;
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	bui(1);
	for(int i=1;i<=m;i++){
		int c,ll,rr;
		double k;
		cin>>c;
		if(c==1) {
			cin>>ll>>rr>>k;
			ch(ll,rr,1,k);
		}
		if(c==2){
			cin>>ll>>rr;
			ansc=qs(ll,rr,1)/(1.0*(rr-ll+1));
			printf("%.4lf\n",ansc);
		}
		if(c==3){
			cin>>ll>>rr;
			ansc=qs(ll,rr,1)/(1.0*(rr-ll+1));
			ansp=qs2(ll,rr,1)/(1.0*(rr-ll+1));
			printf("%.4lf\n",ansp-ansc*ansc);
		}
	}
	return 0;
}
2023/8/3 00:47
加载中...