rt记录,样例都没过QAQ:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m;
double t1[N<<2],t2[N<<2],tag[N<<2];
inline int lc(int x){
return x<<1;
}
inline int rc(int x){
return x<<1|1;
}
inline double pw(double x){
return x*x;
}
void pushup(int x){
t1[x]=t1[lc(x)]+t1[rc(x)];
t2[x]=t2[lc(x)]+t2[rc(x)];
}
void buildtree(int x,int l,int r){
if(l==r){
scanf("%lf",&t1[x]);
t2[x]=pw(t1[x]);
return ;
}
int mid=(l+r)/2;
buildtree(lc(x),l,mid);
buildtree(rc(x),mid+1,r);
pushup(x);
}
void pushdown(int x,int l,int r){
int len=r-l+1;
if(tag[x]){
t1[lc(x)]+=(len-len/2)*tag[x];
t1[rc(x)]+=(len/2)*tag[x];
t2[lc(x)]+=2*tag[x]*t1[lc(x)]+(len-len/2)*tag[x]*tag[x];
t2[rc(x)]+=2*tag[x]*t1[rc(x)]+(len/2)*tag[x]*tag[x];
tag[x]=0;
}
}
void update(int x,int l,int r,int l1,int r1,double d){
if(l1<=l&&r<=r1){
t1[x]+=d*(r-l+1);
t2[x]+=2*d*t1[x]+d*d*(r-l+1);
tag[x]+=d;
return ;
}
pushdown(x,l,r);
int mid=(l+r)/2;
if(l1<=mid)update(lc(x),l,mid,l1,r1,d);
if(mid<r1)update(rc(x),mid+1,r,l1,r1,d);
pushup(x);
}
double query1(int x,int l,int r,int l1,int r1){
if(l1<=l&&r<=r1) return t1[x];
pushdown(x,l,r);
int mid=(l+r)/2;
double res=0;
if(l1<=mid)res+=query1(lc(x),l,mid,l1,r1);
if(mid<r1)res+=query1(rc(x),mid+1,r,l1,r1);
return res;
}
double query2(int x,int l,int r,int l1,int r1){
if(l1<=l&&r<=r1) return t2[x];
pushdown(x,l,r);
int mid=(l+r)/2;
double res=0;
if(l1<=mid)res+=query2(lc(x),l,mid,l1,r1);
if(mid<r1)res+=query2(rc(x),mid+1,r,l1,r1);
return res;
}
signed main(){
int op,x,y;
double k;
scanf("%d%d",&n,&m);
buildtree(1,1,n);
while(m--){
scanf("%d",&op);
if(op==1){
scanf("%d%d%lf",&x,&y,&k);
update(1,1,n,x,y,k);
}else if(op==2){
scanf("%d%d",&x,&y);
printf("%.4lf\n",query1(1,1,n,x,y)/(y-x+1));
}else{
scanf("%d%d",&x,&y);
double num1=query2(1,1,n,x,y)/(y-x+1);
double num2=query1(1,1,n,x,y)/(y-x+1);
printf("%.4lf\n",num1-pw(num2));
}
}
return 0;
}