RT,样例能过,下载了第一个数据点跟它的输出一模一样却全wa,不明白是为什么
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long n,m;
double a[100010];
double sum[400010],add[400010];
double ave[400010],s[400010];
struct node{
double ll,summ;
double av,ss;
};
void build(long long k,long long l,long long r) {
if(l == r) {
sum[k] = a[l];
ave[k] = a[l];
return;
}
long long mid = l+r>>1;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
sum[k] = sum[k*2] + sum[k*2+1];
long long ls = mid-l+1,rs = r-mid,ll = r-l+1;
ave[k] = sum[k] / (ll*1.0);
s[k] = (double)ls*1.0/ll*(s[k*2] + (ave[k*2] - ave[k]) * (ave[k*2] - ave[k])) + (double)rs*1.0/ll*(s[k*2+1] + (ave[k*2+1] - ave[k]) * (ave[k*2+1] - ave[k]));
}
void Add(long long k,long long l,long long r,double v) {
add[k] += v;
sum[k] += (r-l+1) * v;
ave[k] += v;
}
void pushdown(long long k,long long l,long long r,long long mid) {
Add(k*2,l,mid,add[k]);
Add(k*2+1,mid+1,r,add[k]);
add[k] = 0;
}
void modify(long long k,long long l,long long r,long long x,long long y,double v) {
if(l > y || r < x) return;
if(l >= x && r <= y) return Add(k,l,r,v);
long long mid = l+r>>1;
pushdown(k,l,r,mid);
modify(k*2,l,mid,x,y,v);
modify(k*2+1,mid+1,r,x,y,v);
sum[k] = sum[k*2] + sum[k*2+1];
long long ls = mid-l+1,rs = r-mid,ll = r-l+1;
ave[k] = sum[k] / (ll*1.0);
s[k] = (double)ls*1.0/(ll*1.0)*(s[k*2] + (ave[k*2] - ave[k]) * (ave[k*2] - ave[k])) + (double)rs*1.0/ll*(s[k*2+1] + (ave[k*2+1] - ave[k]) * (ave[k*2+1] - ave[k]));
}
inline void pushup(node &res,const node &aa,const node &bb) {
res.summ = aa.summ + bb.summ;
res.ll = aa.ll + bb.ll;
res.av = res.summ*1.0 / res.ll;
res.ss = (double)aa.ll*1.0/res.ll*(aa.ss + (aa.av - res.av) * (aa.av - res.av)) + (double)bb.ll*1.0/res.ll*(bb.ss + (bb.av - res.av) * (bb.av - res.av));
}
node query(long long k,long long l,long long r,long long x,long long y) {
if(l > y || r < x) {
node res;
res.summ = 0;
res.ll = 0;
res.av = 0;
res.ss = 0;
return res;
}
if(l >= x && r <= y) {
node res;
res.summ = sum[k];
res.ll = r-l+1;
res.av = ave[k];
res.ss = s[k];
return res;
}
long long mid = l+r>>1;
pushdown(k,l,r,mid);
node res;
if(x <= mid && y >= mid) {
pushup(res,query(k*2,l,mid,x,y),query(k*2+1,mid+1,r,x,y));
return res;
}
else if(mid <= x && r >= x) res = query(k*2+1,mid+1,r,x,y);
else if(mid >= y && l <= y) res = query(k*2,l,mid,x,y);
return res;
}
int main() {
cin >> n >> m;
for(long long i = 1;i <= n;i++) {
cin >> a[i];
}
build(1,1,n);
for(long long i = 1;i <= m;i++) {
long long t,x,y;
double k;
cin >> t;
if(t == 1) {
cin >> x >> y >> k;
modify(1,1,n,x,y,k);
}
else if(t == 2) {
cin >> x >> y;
printf("%.4llf\n",query(1,1,n,x,y).av);
}
else {
cin >> x >> y;
printf("%.4llf\n",query(1,1,n,x,y).ss);
}
}
return 0;
}