开了两颗树,一颗求和一颗求各个数的平方的和
WA #1 的数据中我的程序输出有较大偏差,不像精度问题,个人码风还比较整洁,思路应该没问题,请问是还有什么特殊情况没考虑到吗?
#include<bits/stdc++.h>
#define mmt(a,b) memset(a,b,sizeof(a))
#define test(x) cout<<#x<<" = "<<x<<endl
#define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
#define endl '\n'
#define enter putchar(endl)
#define ls i<<1
#define rs i<<1|1
// #define double long double
//#define int long long
using namespace std
const int inf=0x3f3f3f3f,N=1e5+10;
int n,m;
double a[N];
int pow2(int x)
{
return x*x;
}
double _pow2(double x)
{
return x*x;
}
struct Tree
{
struct node{
int l,r;
double val,lazy;
}tree[N<<2];
int len(int i)
{
return tree[i].r-tree[i].l+1;
}
void build(int l,int r,int i)
{
tree[i].l=l; tree[i].r=r; tree[i].lazy=0;
if(l==r)
{
tree[i].val=a[l];
return;
}
int mid=l+r>>1;
build(l,mid,ls);
build(mid+1,r,rs);
tree[i].val=tree[ls].val+tree[rs].val;
}
void pushdown(int i)
{
tree[ls].lazy+=tree[i].lazy; tree[rs].lazy+=tree[i].lazy;
tree[ls].val+=tree[i].lazy* (tree[ls].r-tree[ls].l+1);
tree[rs].val+=tree[i].lazy* (tree[rs].r-tree[rs].l+1);
tree[i].lazy=0;
}
void modify(double x,int l,int r,int i)
{
if(l<=tree[i].l&&tree[i].r<=r)
{
tree[i].val+=x*(tree[i].r-tree[i].l+1);
tree[i].lazy+=x;
return;
}
pushdown(i);
if(tree[ls].r>=l)modify(x,l,r,ls);
if(tree[rs].l<=r)modify(x,l,r,rs);
tree[i].val=tree[ls].val+tree[rs].val;
}
double query(int l,int r,int i)
{
if(l<=tree[i].l&&tree[i].r<=r)
return tree[i].val;
pushdown(i);
double res=0;
if(l<=tree[ls].r)res+=query(l,r,ls);
if(tree[rs].l<=r)res+=query(l,r,rs);
return res;
}
}t1;
struct Tree2
{
struct node{
int l,r;
double val,lazy;
}tree[N<<2];
int len(int i)
{
return tree[i].r-tree[i].l+1;
}
void build(int l,int r,int i)
{
tree[i].l=l; tree[i].r=r; tree[i].lazy=0;
if(l==r)
{
tree[i].val= a[l]*a[l];
return;
}
int mid=l+r>>1;
build(l,mid,ls);
build(mid+1,r,rs);
tree[i].val=tree[ls].val+tree[rs].val;
}
void pushdown(int i)
{
tree[ls].lazy+=tree[i].lazy; tree[rs].lazy+=tree[i].lazy;
tree[ls].val+=pow2(tree[i].lazy) * len(ls) +
tree[i].lazy*t1.query(tree[ls].l,tree[ls].r,1)*2;
tree[rs].val+=pow2(tree[i].lazy) * len(rs) +
tree[i].lazy*t1.query(tree[rs].l,tree[rs].r,1)*2;
tree[i].lazy=0;
}
void modify(double x,int l,int r,int i)
{
if(l<=tree[i].l&&tree[i].r<=r)
{
tree[i].val+=pow2(x)*len(i) + t1.query(tree[i].l,tree[i].r,1)*2*x;
tree[i].lazy+=x;
return;
}
pushdown(i);
if(tree[ls].r>=l)modify(x,l,r,ls);
if(tree[rs].l<=r)modify(x,l,r,rs);
tree[i].val=tree[ls].val+tree[rs].val;
}
double query(int l,int r,int i)
{
if(l<=tree[i].l&&tree[i].r<=r)
return tree[i].val;
pushdown(i);
double res=0;
if(l<=tree[ls].r)res+=query(l,r,ls);
if(tree[rs].l<=r)res+=query(l,r,rs);
return res;
}
}t2;
signed main()
{
int i,j;
cin>>n>>m;
for(i=1;i<=n;i++)
cin>>a[i];
t1.build(1,n,1);
t2.build(1,n,1);
while(m--)
{
int op,l,r;
double x;
cin>>op>>l>>r;
if(op==1)
{
cin>>x;
t2.modify(x,l,r,1);
t1.modify(x,l,r,1);
}
if(op==2)
printf("%.4lf\n",t1.query(l,r,1)*1.0/(r-l+1));
if(op==3)
printf("%.4lf\n",1.0*t2.query(l,r,1) / (r-l+1) - _pow2( t1.query(l,r,1)*1.0 / (r-l+1) ) );
}
return 0;
}