P1471 线段树 30pts 7 TLE ?
#include <bits/stdc++.h>
using namespace std;
double sum[100010<<2],sumsum[100010<<2];
double add[100010<<2];
int n,m;
struct node{
double sum,sumsum;
};
void pushup(int now){
sum[now]=sum[now<<1]+sum[now<<1|1];
sumsum[now]=sumsum[now<<1]+sumsum[now<<1|1];
return ;
}
void Add(int l,int r,int now,double k){
add[now]+=k;
sumsum[now]+=2*sum[now]*k+(r-l+1)*k*k;
sum[now]+=(r-l+1)*k;
return ;
}
void pushdown(int l,int r,int now){
if(add[now]){
int m=l+r>>1;
Add(l,m,now<<1,add[now]);
Add(m+1,r,now<<1|1,add[now]);
add[now]=0;
}
return ;
}
void build(int l,int r,int now){
if(l==r){
cin>>sum[now];
sumsum[now]=sum[now]*sum[now];
return;
}
int m=l+r>>1;
build(l,m,now<<1);
build(m+1,r,now<<1|1);
pushup(now);
return ;
}
void change(int l,int r,int now,int x,int y,double k){
if(l>=x&&r<=y){
Add(l,r,now,k);
return ;
}
if(add[now]) pushdown(l,r,now);
int m=l+r>>1;
if(x<=m) change(l,m,now<<1,x,y,k);
if(y>m) change(m+1,r,now<<1|1,x,y,k);
pushup(now);
return ;
}
node query(int l,int r,int now,int x,int y){
if(l>=x&&r<=y){
node a={sum[now],sumsum[now]};
return a;
}
if(add[now]) pushdown(l,r,now);
int m=l+r>>1;
node a={0,0};
if(x<=m){
a.sum+=query(l,m,now<<1,x,y).sum;
a.sumsum+=query(l,m,now<<1,x,y).sumsum;
}
if(y>m){
a.sum+=query(m+1,r,now<<1|1,x,y).sum;
a.sumsum+=query(m+1,r,now<<1|1,x,y).sumsum;
}
return a;
}
signed main(){
cin>>n>>m;
build(1,n,1);
for(int i=1;i<=m;i++){
int op;
cin>>op;
if(op==1){
int x,y;
cin>>x>>y;
double k;
cin>>k;
change(1,n,1,x,y,k);
}
else if(op==2){
int x,y;
cin>>x>>y;
node a=query(1,n,1,x,y);
printf("%.4lf\n",a.sum/(y-x+1));
}
else{
int x,y;
cin>>x>>y;
node a=query(1,n,1,x,y);
printf("%.4lf\n",a.sumsum/(y-x+1)-(a.sum/(y-x+1)*a.sum/(y-x+1)));
}
}
}