不知道为啥,似乎精度爆炸了,但开long double后还是爆炸,心态直接崩溃,求调,悬赏关注。
#include<bits/stdc++.h>
#define ri register int
#define sq_(x) x*x
#define ll long long
#pragma G++ optimize(3)
using namespace std;
struct node{
int l,r,gs;
double lz;
double s,sq;
}tree[400010];
int n,m;
double z[100010];
void u(int k)
{
tree[k].s=tree[k<<1].s+tree[k<<1|1].s;
tree[k].sq=tree[k<<1].sq+tree[k<<1|1].sq;
}
void d(int k)
{
tree[k<<1].sq+=(2.0000*tree[k].lz*tree[k<<1].s+tree[k].gs*sq_(tree[k].lz));
tree[k<<1|1].sq+=(2.00000*tree[k].lz*tree[k<<1].s+tree[k].gs*sq_(tree[k].lz));
tree[k<<1].s+=(tree[k<<1].gs*tree[k].lz);
tree[k<<1|1].s+=(tree[k<<1|1].gs*tree[k].lz);
tree[k<<1].lz+=tree[k].lz;
tree[k<<1|1].lz+=tree[k].lz;
tree[k].lz=0;
}
void build(int k,int l,int r)
{
tree[k].l=l,tree[k].r=r,tree[k].gs=r-l+1;
if(l==r)
{
tree[k].s=z[l];
tree[k].sq=sq_(tree[k].s);
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
u(k);
}
void change(int k,int l,int r,double v)
{
if(tree[k].l>=l&&tree[k].r<=r)
{
tree[k].sq+=(2.0000*v*tree[k].s+tree[k].gs*sq_(v));
tree[k].s+=(tree[k].gs*v);
tree[k].lz+=v;
return;
}
d(k);
int mid=(tree[k].l+tree[k].r)>>1;
if(l<=mid)change(k<<1,l,r,v);
if(r>mid)change(k<<1|1,l,r,v);
u(k);
}
double q1(int k,int l,int r)
{
if(tree[k].l>=l&&tree[k].r<=r)
{
return tree[k].s;
}
d(k);
int mid=(tree[k].l+tree[k].r)>>1;
double ans=0;
if(l<=mid)ans+=q1(k<<1,l,r);
if(r>mid)ans+=q1(k<<1|1,l,r);
return ans;
}
double q2(int k,int l,int r)
{
if(tree[k].l>=l&&tree[k].r<=r)
{
return tree[k].sq;
}
d(k);
int mid=(tree[k].l+tree[k].r)>>1;
double ans=0;
if(l<=mid)ans+=q2(k<<1,l,r);
if(r>mid)ans+=q2(k<<1|1,l,r);
return ans;
}
int main ()
{
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>z[i];
build(1,1,n);
for(int j=1;j<=m;j++)
{
int op,l,r;
double k;
cin>>op>>l>>r;
if(op==1)
{
cin>>k;
change(1,l,r,k);
}
if(op==2)
{
double ans=q1(1,l,r)/((r-l+1)*1.0000);
printf("%.4f\n",ans);
}
if(op==3)
{
double pf=q2(1,l,r),qj=q1(1,l,r),ans=0;
int gss=r-l+1;
ans=pf/(gss*1.0000)-sq_(qj)/(sq_(gss)*1.0000);
printf("%.4f\n",ans);
}
}
return 0;
}