修改是将一区间的值全加x
查询是查询一区间的方差
利用方差公式D(x)=E(x^2)-E(x)^2
维护区间和和区间平方和,更新的时候要lazy,更新平方和根据完全平方来
运行了两秒半但是WA了,怀疑数据有错,到现在也没人A,先把代码记录下来
#include<stdio.h>
#include<string.h>
#define MAXN 500005
#define ll long long
#define lch p<<1
#define rch p<<1|1
struct node
{
int l,r;
ll sum,sum2;
ll val;
}t[MAXN*4];
void construct(int l,int r,int p)
{
t[p].l=l,t[p].r=r,t[p].sum=t[p].sum2=t[p].val=0;
if(l==r)
{
scanf("%lld",&t[p].sum);
t[p].sum2=t[p].sum*t[p].sum;
return ;
}
int m=(l+r)>>1;
construct(l,m,lch);
construct(m+1,r,rch);
t[p].sum=t[lch].sum+t[rch].sum;
t[p].sum2=t[lch].sum2+t[rch].sum2;
}
void pushdown(int p)
{
t[lch].val+=t[p].val;
t[rch].val+=t[p].val;
t[lch].sum2+=2*t[lch].sum*t[p].val+(t[lch].r-t[lch].l+1)*t[p].val*t[p].val;
t[lch].sum+=t[p].val*(t[lch].r-t[lch].l+1);
t[rch].sum2+=2*t[rch].sum*t[p].val+(t[rch].r-t[rch].l+1)*t[p].val*t[p].val;
t[rch].sum+=t[p].val*(t[rch].r-t[rch].l+1);
t[p].val=0;
}
void query(int l,int r,int p,ll &ans1,ll &ans2)
{
if(t[p].l==l&&t[p].r==r)
{
ans1+=t[p].sum;
ans2+=t[p].sum2;
return ;
}
if(t[p].val) pushdown(p);
int m=(t[p].l+t[p].r)>>1;
if(r<=m) query(l,r,lch,ans1,ans2);
else if(l>m) query(l,r,rch,ans1,ans2);
else query(l,m,lch,ans1,ans2),query(m+1,r,rch,ans1,ans2);
}
void modify(int l,int r,ll val,int p)
{
if(t[p].l==l&&t[p].r==r)
{
t[p].val+=val;
t[p].sum2+=2*t[p].sum*val+(t[p].r-t[p].l+1)*val*val;
t[p].sum+=val*(t[p].r-t[p].l+1);
return ;
}
if(t[p].val) pushdown(p);
int m=(t[p].l+t[p].r)>>1;
if(r<=m) modify(l,r,val,lch);
else if(l>m) modify(l,r,val,rch);
else modify(l,m,val,lch),modify(m+1,r,val,rch);
t[p].sum=t[lch].sum+t[rch].sum;
t[p].sum2=t[lch].sum2+t[rch].sum2;
}
ll getans(ll x,ll x2,int n)
{
return (x2*n-x*x)/(n*n);
}
int main()
{
int n,m;
int op,l,r;
ll ans1,ans2,x;
while(scanf("%d%d",&n,&m)!=EOF)
{
construct(0,n-1,1);
while(m--)
{
scanf("%d%d%d",&op,&l,&r);
if(op==1)
{
scanf("%lld",&x);
modify(l,r,x,1);
}
else
{
ans1=ans2=0;
query(l,r,1,ans1,ans2);
//printf("asn1:%d asn2:%d\n",ans1,ans2);
printf("%lld\n",getans(ans1,ans2,(r-l+1)));
}
}
}
return 0;
}