悬关求调
查看原帖
悬关求调
738882
OIer_dcy__AK_IOI楼主2024/12/15 13:49

样例过了全WA

#include<bits/stdc++.h>

using namespace std;

const int maxn=1e5+10;
const int maxm=4e5+10;

int n,m;
double a[maxn];
struct Tree{ //线段树维护:和,平方和
	int left,right;
	double tag1,tag2,sum1,sum2; //tag1是和的懒标记,sum1是和;tag2是平方和的懒标记,sum2是平方和
}tree[maxm];

inline void maketag(int root,double k1,double k2,int l,int r){
	tree[root].tag1+=k1;
	tree[root].tag2+=k2;
	tree[root].sum2+=(r-l+1)*k2+2*tree[root].sum1*k1;
	tree[root].sum1+=(r-l+1)*k1;
}

inline void pushdown(int root){
	if(tree[root].left!=tree[root].right){
		int mid=(tree[root].left+tree[root].right)>>1;
		maketag(root<<1,tree[root].tag1,tree[root].tag2,tree[root].left,mid);
		maketag(root<<1|1,tree[root].tag1,tree[root].tag2,mid+1,tree[root].right);
		tree[root].tag1=0;
		tree[root].tag2=0;
	}
	return;
}

inline void build(int root,int l,int r){
	// cout<<root<<" "<<l<<" "<<r<<"\n";
	tree[root].left=l;
	tree[root].right=r;
	if(tree[root].left==tree[root].right){
		tree[root].sum1=a[tree[root].left];
		tree[root].sum2=a[tree[root].left]*a[tree[root].left];
		return;
	}
	int mid=(tree[root].left+tree[root].right)>>1;
	build(root<<1,l,mid);
	build(root<<1|1,mid+1,r);
	tree[root].sum1=tree[root<<1].sum1+tree[root<<1|1].sum1;
	tree[root].sum2=tree[root<<1].sum2+tree[root<<1|1].sum2;
}

inline void update(int root,int l,int r,double k){
	pushdown(root);
	if(l<=tree[root].left&&r>=tree[root].right){
		maketag(root,k,k*k,tree[root].left,tree[root].right);
		return;
	}
	int mid=(tree[root].left+tree[root].right)>>1;
	if(l<=mid) update(root<<1,l,r,k);
	if(r>mid) update(root<<1|1,l,r,k);
	tree[root].sum1=tree[root<<1].sum1+tree[root<<1|1].sum1;
	tree[root].sum2=tree[root<<1].sum2+tree[root<<1|1].sum2;
}

inline double query1(int root,int l,int r){
	pushdown(root);
	if(l<=tree[root].left&&r>=tree[root].right){
		return tree[root].sum1;
	}
	double res=0;
	int mid=(tree[root].left+tree[root].right)>>1;
	if(l<=mid) res+=query1(root<<1,l,r);
	if(r>mid) res+=query1(root<<1|1,l,r);
	return res;
}

inline double query2(int root,int l,int r){
	pushdown(root);
	if(l<=tree[root].left&&r>=tree[root].right){
		return tree[root].sum2;
	}
	double res=0;
	int mid=(tree[root].left+tree[root].right)>>1;
	if(l<=mid) res+=query2(root<<1,l,r);
	if(r>mid) res+=query2(root<<1|1,l,r);
	return res;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%lf",&a[i]);
	}

	build(1,1,n);

	while(m--){
		int op;
		scanf("%d",&op);
		if(op==1){
			int x,y;
			double k;
			scanf("%d%d%lf",&x,&y,&k);
			update(1,x,y,k);
		}
		if(op==2){
			int x,y;
			scanf("%d%d",&x,&y);
			printf("%.4lf\n",1.0*query1(1,x,y)/(y-x+1));
		}
		if(op==3){
			int x,y;
			scanf("%d%d",&x,&y);
			double sum=query1(1,x,y);
			double ave=1.0*sum/(y-x+1); 
			double pow_sum=query2(1,x,y);
			// cout<<pow_sum<<" "<<sum<<" "<<ave<<"\n";
			printf("%.4lf\n",1.0*(pow_sum-2.0*ave*sum+ave*ave*(y-x+1))/(y-x+1));
		}
	}
	return 0;
}
2024/12/15 13:49
加载中...