代码
#include<bits/stdc++.h>
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define N 100010
/*tips:
1: ql--l--r--qr
2: tag+k,b+=(nk^2+2k(x1+x2+x3+...+xn))
*/
using namespace std;
double a[N<<2],b[N<<2],tag[N<<2],c[N];
//a是维护区间和,b是维护区间平方和,tag就是懒标记,c用来读入
void pushup(int o){
a[o]=a[o<<1]+a[o<<1|1];
b[o]=b[o<<1]+b[o<<1|1];//
}//c
void pushdown(int o,int l,int r){
if(tag[o]){
int mid=l+r>>1;
tag[o<<1]+=tag[o],tag[o<<1|1]+=tag[o];
b[o<<1]+=2*tag[o]*a[o<<1]+(mid-l+1)*tag[o]*tag[o];//
b[o<<1|1]+=2*tag[o]*a[o<<1|1]+(r-mid)*tag[o]*tag[o];//
a[o<<1]+=tag[o]*(mid-l+1);
a[o<<1|1]+=tag[o]*(r-mid);
tag[o]=0;
}
}//平方和更新见tip2
void build(int o,int l,int r){
if(l==r){
a[o]=c[l];
b[o]=a[o]*a[o];//
return ;
}
int mid=l+r>>1;
build(lson);
build(rson);
pushup(o);
}
void update(int o,int l,int r,int ql,int qr,double x){
if(ql<=l&&r<=qr){
tag[o]+=x;
b[o]+=(2*x*a[o]+(r-l+1)*x*x);///*tag+k,b+(nk^2+2k(x1+x2+x3+...+xn))*/
a[o]+=(r-l+1)*x;
return ;
}
pushdown(o,l,r);
int mid=l+r>>1;
if(mid>=ql) update(lson,ql,qr,x);
if(mid<qr) update(rson,ql,qr,x);
pushup(o);
}
double qa(int o,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr){
return a[o];
}
pushdown(o,l,r);
int mid=l+r>>1;
double res=0;
if(mid>=ql) res+=qa(lson,ql,qr);
if(mid<qr) res+=qa(rson,l,qr);
return res;
}
double qb(int o,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr){
return b[o];
}
pushdown(o,l,r);
int mid=l+r>>1;
double res=0;
if(mid>=ql) res+=qb(lson,ql,qr);
if(mid<qr) res+=qb(rson,l,qr);
return res;
}//
int n,m,x,y,opt;
double num=0;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>c[i];
}
build(1,1,n);
for(int i=1;i<=m;i++){
cin>>opt;
if(opt==1){
cin>>x>>y>>num;
update(1,1,n,x,y,num);
}
if(opt==2){
cin>>x>>y;
printf("%.4lf\n",qa(1,1,n,x,y)/(y-x+1));
}
if(opt==3){
cin>>x>>y;
double len=y-x+1;
double s1=qb(1,1,n,x,y)/len;
double s2=qa(1,1,n,x,y)/len;
double ans=s1-s2*s2;
printf("%.4lf\n",ans);
}
}
}
试了用long double,但没用。调了将近一个多小时了,人都要炸了www
大佬帮帮