30分,调了半天求助啊 ( /bx
#include<stdio.h>
#include<math.h>
#define LF "%.4lf\n"
const int N=int(1e5)+1;
double read(){
double a;
scanf("%lf",&a);
return a;
}
double sqr(double x){
return x*x;
}
struct{double s1,s2,tg=0.;}tr[N*4];
#define s1(h) tr[h].s1
#define s2(h) tr[h].s2
#define tg(h) tr[h].tg
#define TREE int h,int l,int r
#define ls h<<1
#define rs h<<1|1
#define mid (l+r>>1)
#define Lson ls,l,mid
#define Rson rs,mid+1,r
void push_up(int h){
s1(h)=s1(ls)+s1(rs);
s2(h)=s2(ls)+s2(rs);
}
void make_tag(int h,int len,double x){
s2(h)+=2*x*s1(h)+len*x*x;
s1(h)+=len*x;tg(h)+=x;
}
void push_down(int h,int len){
if(fabs(tg(h))<1e-7)return;
make_tag(ls,len/2,tg(h));
make_tag(rs,len-len/2,tg(h));
tg(h)=0;
}
void build(TREE){
//printf("build:%d %d %d\n",h,l,r);
if(l==r)s2(h)=sqr(s1(h)=read());
else build(Lson),build(Rson),push_up(h);
//printf("pushed up:h:%d s1:%.0lf,s2:%.0lf\n",h,s1(h),s2(h));
}
double query(TREE,int x,int y,bool z){
//printf("query:%d %d %d %d %d\n",h,l,r,x,y);
if(x<=l&&r<=y) return z?s2(h):s1(h);
push_down(h,r-l+1);
if(y<=mid) return query(Lson,x,y,z);
if(x>mid) return query(Rson,x,y,z);
return query(Lson,x,y,z)+query(Rson,x,y,z);
}
void update(TREE,int x,int y,double z){
//printf("update:%d %d %d %d %d\n",h,l,r,x,y);
if(x<=l&&r<=y) return make_tag(h,r-l+1,z);
push_down(h,r-l+1);
if(x<=mid) update(Lson,x,y,z);
if(y>mid) update(Rson,x,y,z);
push_up(h);
}
main(){
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
//putchar(1);
int n,m;
scanf("%d%d",&n,&m);
build(1,1,n);
for(int opt,x,y;m--;){
scanf("%d%d%d",&opt,&x,&y);
if(opt==1) update(1,1,n,x,y,read());
else{
int len=y-x+1;
double x1=query(1,1,n,x,y,0)/len;
if(opt==2) printf(LF,x1);
else{
double x2=query(1,1,n,x,y,1)/len;
printf(LF,x2-x1*x1);
}
}
}
}
样例2 开始很多数都有了些细微的差距