线段树班长0分求调
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define dd double
struct node{
ll l,r;
dd lazy,x,x2;
}t[400009];
ll n,m,b,c,d,a;
dd o,s[400009];
void push_up(ll p)
{
t[p].x=t[2*p].x+t[2*p+1].x;
t[p].x2=t[2*p].x2+t[2*p+1].x2;
}
void push_down(ll p)
{
ll u=t[p].lazy;
t[p*2].x2+=2*u*t[p*2].x+(t[p*2].r-t[p*2].l+1)*u*u;
t[p*2+1].x2+=2*u*t[p*2+1].x+(t[p*2+1].r-t[p*2+1].l+1)*u*u;
t[p*2].x+=t[p].lazy*(t[p*2].r-t[p*2].l+1);
t[p*2+1].x+=t[p].lazy*(t[p*2+1].r-t[p*2+1].l+1);
t[p*2].lazy+=t[p].lazy;
t[p*2+1].lazy+=t[p].lazy;
t[p].lazy=0;
}
void build(ll p,ll l,ll r)
{
t[p].l=l,t[p].r=r,t[p].lazy=0;
if(l==r)
{
t[p].x=s[l];
t[p].x2=s[l]*s[l];
return ;
}
ll mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
push_up(p);
}
void update(ll p,ll l,ll r,dd u)
{
if(l<=t[p].l&&r>=t[p].r)
{
t[p].x2+=2*u*t[p].x+(t[p].r-t[p].l+1)*u*u;
t[p].x+=u*(t[p].r-t[p].l+1);
t[p].lazy+=u;
return ;
}
push_down(p);
ll mid=(t[p].l+t[p].r)/2;
if(l<=mid)
update(p*2,l,r,u);
if(r>mid)
update(p*2+1,l,r,u);
push_up(p);
}
dd getsum(ll p,ll l,ll r)
{
if(l<=t[p].l&&r>=t[p].r)
{
return t[p].x;
}
push_down(p);
ll mid=(t[p].l+t[p].r)/2,ans=0;
if(l<=mid)
ans+=getsum(p*2,l,r);
if(r>mid)
ans+=getsum(p*2+1,l,r);
return ans;
}
dd getsum2(ll p,ll l,ll r)
{
if(l<=t[p].l&&r>=t[p].r)
{
return t[p].x2;
}
push_down(p);
ll mid=(t[p].l+t[p].r)/2,ans=0;
if(l<=mid)
ans+=getsum(p*2,l,r);
if(r>mid)
ans+=getsum(p*2+1,l,r);
return ans;
}
int main()
{
cin>>n>>m;
for(ll i=1;i<=n;i++)
{
cin>>s[i];
}
build(1,1,n);
for(ll i=1;i<=m;i++)
{
cin>>d;
if(d==1)
{
cin>>a>>b>>o;
update(1,a,b,o);
}
else if(d==2)
{
cin>>a>>b;
double e=getsum(1,a,b)/(b-a+1);
printf("%.4lf\n",e);
}
else
{
cin>>a>>b;
double e=getsum2(1,a,b);
e=e/(b-a+1);
double f=getsum(1,a,b)/(b-a+1);
e-=f*f;
printf("%.4lf\n",e);
}
}
return 0;
}