分块40分求调
  • 板块P1471 方差
  • 楼主FreeEvil767
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/7/15 17:35
  • 上次更新2024/7/15 18:51:08
查看原帖
分块40分求调
903834
FreeEvil767楼主2024/7/15 17:35
#include <bits/stdc++.h>
using namespace std;
int n,q,id[100009],m;
double x[100009],sum[100009],sqsum[100009],d[100009],k;
double add(int l,int r){
	double psum=0;
	if (id[l]==id[r]) for (int i=l;i<=r;++i) psum+=x[i]+d[id[i]];
	else{
		for (int i=l;id[i]==id[l];++i) psum+=x[i]+d[id[i]];
		for (int i=(id[r]-1)*m+1;i<=r;++i) psum+=x[i]+d[id[i]];
		for (int i=id[l]+1;i<=id[r]-1;++i) psum+=sum[i]+d[i]*m;
	}
	return psum;
}
int main(){
	cin>>n>>q;m=round(sqrt(n*1.0));for (int i=1;i<=n;++i) id[i]=ceil(i*1.0/m);
	for (int i=1;i<=n;++i) cin>>x[i],sum[id[i]]+=x[i],sqsum[id[i]]+=x[i]*x[i];
	for (int t=1,op,l,r;t<=q;++t){
		cin>>op>>l>>r;
		if (op==1){
			cin>>k;
			if (id[l]==id[r]) for (int i=l;i<=r;++i) sqsum[id[i]]+=x[i]*k*2+k*k,x[i]+=k,sum[id[i]]+=k;
			else{
				for (int i=l;id[i]==id[l];++i) x[i]+=k,sum[id[i]]+=k,sqsum[id[i]]+=(x[i]-k)*k*2+k*k;
				for (int i=(id[r]-1)*m+1;i<=r;++i) x[i]+=k,sum[id[i]]+=k,sqsum[id[i]]+=(x[i]-k)*k*2+k*k;
				for (int i=id[l]+1;i<=id[r]-1;++i) d[i]+=k;
			}
		}
		else if (op==2)	printf("%.4lf\n",add(l,r)/(r-l+1));
		else{
			double psqsum=0,avg=add(l,r)/(r-l+1);
			if (id[l]==id[r]) for (int i=l;i<=r;++i) psqsum+=pow(x[i]+d[id[i]],2);
			else{
				for (int i=l;id[i]==id[l];++i) psqsum+=pow(x[i]+d[id[i]],2);
				for (int i=(id[r]-1)*m+1;i<=r;++i) psqsum+=pow(x[i]+d[id[i]],2);
				for (int i=id[l]+1;i<=id[r]-1;++i) psqsum+=sqsum[i]+2*d[i]*(sum[i]+m*d[i])+m*d[i]*d[i];
			}
		//	for (int i=1;i<=id[n];++i) printf("%.4lf ",sqsum[i]);
		//	printf("%.4lf\n",psqsum);
			double res=psqsum/(r-l+1)-avg*avg;
			printf("%.4lf\n",res);
		}
	}
	return 0;
}
2024/7/15 17:35
加载中...