萌新求调线段树
查看原帖
萌新求调线段树
1407356
wo_yao_shua_ti楼主2024/8/17 21:13

提交记录

爆了六个点,求各位大佬帮忙看看

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m,w,x,y;
double z,anss;
double a[1000005];
double tag[1000005]; 
struct node{
	int l;
 	int r;
 	double s;
 	double ss;//square sum
}tree[1000005];
void build(int l,int r,int o){
	tree[o].l=l;
	tree[o].r=r; 
	if(l==r){
		tree[o].s=a[l];
		tree[o].ss=a[l]*a[l]*1.0;
		return;
	}
	int mid=(l+r)>>1; 
	build(l,mid,o*2);
	build(mid+1,r,o*2+1);
	tree[o].s=tree[o*2].s+tree[o*2+1].s;
	tree[o].ss=tree[o*2].ss+tree[o*2+1].ss;
}
void push_down(int o){   
	if(tag[o]==0){
		return;
	}
	tree[o*2].ss+=(tree[o*2].r-tree[o*2].l+1)*tag[o]*tag[o];
	tree[o*2].ss+=2*tree[o*2].s*tag[o];
	tree[o*2].s+=tag[o]*(tree[o*2].r-tree[o*2].l+1);
	tree[o*2+1].ss+=(tree[o*2+1].r-tree[o*2+1].l+1)*tag[o]*tag[o];
	tree[o*2+1].ss+=2*tree[o*2+1].s*tag[o];
	tree[o*2+1].s+=tag[o]*(tree[o*2+1].r-tree[o*2+1].l+1.0);
	tag[o*2]+=tag[o];
	tag[o*2+1]+=tag[o];
	tag[o]=0;
}
void add_up(int l,int r,int o,double v){
	if(tree[o].l>r||tree[o].r<l){
		return ;
	}
	if(tree[o].l>=l&&tree[o].r<=r){
		tree[o].ss+=(tree[o].r-tree[o].l+1.0)*v*v*1.0;
		tree[o].ss+=2.0*tree[o].s*v;
		tree[o].s+=v*(tree[o].r-tree[o].l+1.0);
		tag[o]+=v;
		return;
	}
	push_down(o);
	if(tree[o*2].r>=l){
		add_up(l,r,o*2,v);
	}
	if(tree[o*2+1].l<=r){
		add_up(l,r,o*2+1.0,v);
	}
	tree[o].s=tree[o*2].s+tree[o*2+1].s;
	tree[o].ss=tree[o*2].ss+tree[o*2+1].ss;
}
double summ(int l,int r,int o){
	if(tree[o].l>=l&&tree[o].r<=r){
		return tree[o].s;
	}
	if(tree[o].l>r||tree[o].r<l){
		return 0.0;
	}
	push_down(o);
	double ans=0.0;
	if(tree[o*2].r>=l){
		ans+=summ(l,r,o*2);
	}
	if(tree[o*2+1].l<=r){
		ans+=summ(l,r,o*2+1.0);
	}
	return ans;
}
double vrc(int l,int r,int o){
	if(tree[o].l>=l&&tree[o].r<=r){
		return tree[o].ss;
	}
	if(tree[o].l>r||tree[o].r<l){
		return 0.0;
	}
	push_down(o);
	double ans=0.0;
	if(tree[o*2].r>=l){
		ans+=vrc(l,r,o*2);
	}
	if(tree[o*2+1].l<=r){
		ans+=vrc(l,r,o*2+1);
	}
	return ans;
}
signed main(){
	cin>>n>>m;
	for(int i = 1;i<=n;i++){
		cin>>a[i];
	}
	build(1,n,1);
	while(m--){
		cin>>w>>x>>y;
		if(w==1.0){
			cin>>z;
			add_up(x,y,1.0,z);
		}else if(w==2){
			printf("%.4lf\n",(double)summ(x,y,1.0)*1.0/(y-x+1.0));
		}else{
			anss=(double)summ(x,y,1.0)*1.0/(y-x+1.0);
			anss*=anss;
			printf("%.4lf\n",(double)vrc(x,y,1.0)*1.0/n*1.0-anss);
		}
	}
}

2024/8/17 21:13
加载中...