此处附上我还算看的过去的 code,(看不懂的可以去看看 Dpair 大佬的题解)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
const double eps = 1e-6;
inline void ac(){
std::ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
int n,m;
double a[N];
struct node{
double sum,lazy;
}tr1[N << 3],tr2[N << 3];//tr1 : average_tree ; tr2 : fc_tree
inline void pushup(int pos){
tr1[pos].sum = tr1[pos << 1].sum + tr1[pos << 1 | 1].sum;
tr2[pos].sum = tr2[pos << 1].sum + tr2[pos << 1 | 1].sum;
}
inline void build(int pos,int l,int r){
if(l == r){
tr1[pos].sum = a[l];
tr2[pos].sum = a[l] * a[l];
return ;
}
int mid = (l + r) >> 1;
build(pos << 1,l,mid);
build(pos << 1 | 1,mid + 1,r);
pushup(pos);
}
inline void pushdown(int pos,int l,int r){
int mid = (l + r) >> 1;
tr2[pos << 1].sum += tr1[pos << 1].sum * (mid - l + 1) * 2 + (mid - l + 1) * tr2[pos].lazy *tr2[pos].lazy;
tr2[pos << 1 | 1].sum += tr1[pos << 1 | 1].sum * (r - mid) + (r - mid) * tr2[pos].lazy * tr2[pos].lazy;
tr2[pos << 1].lazy += tr2[pos].lazy;
tr2[pos << 1 | 1].lazy +=tr2[pos].lazy;
tr2[pos].lazy = 0;
tr1[pos << 1].sum += (mid - l + 1) * tr1[pos].lazy;
tr1[pos << 1 | 1].sum += (r - mid) * tr1[pos].lazy;
tr1[pos << 1].lazy += tr1[pos].lazy;
tr1[pos << 1 | 1].lazy +=tr1[pos].lazy;
tr1[pos].lazy = 0;
}
inline void update(int pos,int l,int r,int L,int R,double k){
if(L <= l && r <= R){
tr2[pos].lazy += k;
tr1[pos].lazy += k;
tr2[pos].sum += tr1[pos].sum * 2 * k + (r - l + 1) * k * k;
tr1[pos].sum += (r - l + 1) * k;
return;
}
if(tr1[pos].lazy || tr2[pos].lazy)pushdown(pos,l,r);
int mid = (l + r) >> 1;
if(L <= mid)update(pos << 1,l,mid,L,R,k);
if(R > mid)update(pos << 1 | 1,mid + 1,r,L,R,k);
pushup(pos);
}
inline double query(node tr[],int pos,int l,int r,int L,int R){
if(L <= l && r <= R)return tr[pos].sum;
if(tr[pos].lazy)
pushdown(pos,l,r);
int mid = (l + r) >> 1;
double ret = 0;
if(L <= mid)ret += query(tr,pos << 1,l,mid,L,R);
if(R > mid)ret += query(tr,pos << 1 | 1,mid + 1,r,L,R);
return ret;
}
int main(){
ac();
cin >> n >> m;
for(int i = 1;i <= n;i ++)cin >> a[i];
build(1,1,n);
while(m --){
int opt,l,r;
double k;
cin >> opt >> l >> r;
if(opt == 1){
cin >> k;
update(1,1,n,l,r,k);
}
else if(opt == 2){
double ans = query(tr1,1,1,n,l,r) * 1.0 / ((r - l + 1) * 1.0);
printf("%.4f\n",ans);
}
else {
double ans = query(tr2,1,1,n,l,r) / (1.0 * (r - l + 1)) + query(tr1,1,1,n,l,r) * query(tr1,1,1,n,l,r) / ( (r - l + 1) * (r - l + 1) * 1.0 );
printf("%.4f\n",ans);
}
}
return 0;
}