rt,萌新刚学线段树,WA on #1,2,3,4,8,9,求调 val1区间和,val2区间平方和,query直接返回区间和。
#include<iostream>
#include<iomanip>
using namespace std;
#define N 100005
#define D double
D n,m,op,x,y,t,a[N];
struct node{
int l,r;
D val1,val2,tag;
}seg[4*N];
bool in(int L,int R,int nl,int nr){
return L>=nl&&R<=nr;
}
bool out(int L,int R,int nl,int nr){
return L>nr||R<nl;
}
void mtag(int u,int nl,int nr,D t){
seg[u].val2+=t*t*(nr-nl+1)+2*t*seg[u].val1;
seg[u].tag+=t,seg[u].val1+=(nr-nl+1)*t;
}
void pushdown(int u,int nl,int nr){
int mid=(nl+nr)/2;
mtag(u*2,nl,mid,seg[u].tag);
mtag(u*2+1,mid+1,nr,seg[u].tag);
seg[u].tag=0;
}
void pushup(int u){
seg[u].val1=seg[u*2].val1+seg[u*2+1].val1;
seg[u].val2=seg[u*2].val2+seg[u*2+1].val2;
}
D query1(int typ,int u,int nl,int nr,int L,int R){
if(in(nl,nr,L,R)){
if(typ==1) return seg[u].val1;
else return seg[u].val2;
}
else if(!out(nl,nr,L,R)){
pushdown(u,nl,nr);
int mid=(nl+nr)/2;
return query1(typ,u*2,nl,mid,L,R)+query1(typ,u*2+1,mid+1,nr,L,R);
}
else return 0;
}
D query2(int x,int y){
D a1=query1(2,1,1,n,x,y);
D a2=(D)query1(1,1,1,n,x,y)/(D)(y-x+1);
return (a1+a2*a2*n-2*a2*query1(1,1,1,n,x,y))/(D)(y-x+1);
}
void update(int u,int nl,int nr,int L,int R,D t){
if(in(nl,nr,L,R)) mtag(u,nl,nr,t);
else if(!out(nl,nr,L,R)){
pushdown(u,nl,nr);
int mid=(nl+nr)/2;
update(u*2,nl,mid,L,R,t),update(u*2+1,mid+1,nr,L,R,t);
pushup(u);
}
}
void build(int u,int nl,int nr){
seg[u].l=nl,seg[u].r=nr,seg[u].tag=0;
if(nl==nr){
seg[u].val1=a[nl],seg[u].val2=a[nl]*a[nl];
return;
}
int mid=(nl+nr)/2;
build(u*2,nl,mid),build(u*2+1,mid+1,nr);
pushup(u);
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
while(m--){
cin>>op>>x>>y;
if(op==1) cin>>t,update(1,1,n,x,y,t);
else if(op==2) cout<<setprecision(4)<<fixed<<(D)query1(1,1,1,n,x,y)/(D)(y-x+1)<<endl;
else cout<<setprecision(4)<<fixed<<query2(x,y)<<endl;
}
return 0;
}