10pts求助
查看原帖
10pts求助
632955
伊地知虹夏楼主2023/2/28 16:22
#include<bits/stdc++.h>
#define int long long
using namespace std;
#define l(x) tr[x].l
#define r(x) tr[x].r
#define sum(x) tr[x].sum
#define ave(x) tr[x].aver
#define sq(x) tr[x].sum_q
#define tag(x) tr[x].tag
const int N = 1e5+5;
double a[N];
struct node{
    int l,r;
	double sum,tag,sum_q,aver;
}tr[N*4];
void pushup(int cur){
    sum(cur) = sum(cur<<1)+sum(cur<<1|1);
    sq(cur) = sq(cur<<1)+sq(cur<<1|1);
    ave(cur) = (ave(cur<<1)+ave(cur<<1|1))/2;
    return ;
}
void addtag(int cur,double v){
    tag(cur) += v;
    sum(cur) += (r(cur)-l(cur)+1)*v;
    sq(cur) += 2*v*sum(cur)+(r(cur)-l(cur)+1)*v*v;
    ave(cur) += v;
}
void pushdown(int cur){
	if(tag(cur) == 0) return ;
	addtag(cur<<1,tag(cur));
	addtag(cur<<1|1,tag(cur));
	tag(cur) = 0;
	return ;
}
void build(int cur,int l,int r){
    tr[cur] = (node){l,r};
    if(l == r){
        sum(cur) = a[l];
        return ;
    }
    int mid = l+r >> 1;
    build(cur<<1,l,mid),build(cur<<1|1,mid+1,r);
    pushup(cur);
    return ;
}
double q_aver(int cur,int x,int y){
	if(l(cur) > y || r(cur) < x) return 1e18;
	if(l(cur) >= x && r(cur) <= y) return ave(cur);
	pushdown(cur);
	int f = q_aver(cur<<1,x,y),g = q_aver(cur<<1|1,x,y);
	if(f == 1e18) return g;
	if(g == 1e18) return f;
	return (g+f)/2;
}
double q_sum_q(int cur,int x,int y){
    if(l(cur) > y || r(cur) < x) return 0;
	if(l(cur) >= x && r(cur) <= y) return tr[cur].sum_q;
	pushdown(cur);
	return q_sum_q(cur<<1,x,y)+q_sum_q(cur<<1|1,x,y);
}
double q_sum(int cur,int x,int y){
    if(l(cur) > y || r(cur) < x) return 0;
	if(l(cur) >= x && r(cur) <= y) return tr[cur].sum;
	pushdown(cur);
	return q_sum_q(cur<<1,x,y)+q_sum_q(cur<<1|1,x,y);
}
double q_fc(int x,int y){
	double aver = q_aver(1,x,y);
	double sum_q = q_sum(1,x,y);
	double sum = q_sum(1,x,y);
	return (y-x+1)*aver*aver-2*aver*sum+sum_q;
}
void modify(int cur,int x,int y,double v){
	if(l(cur) > y || r(cur) < x) return ;
	if(l(cur) >= x && r(cur) <= y){
		addtag(cur,v);
		return ;
	}
	pushdown(cur);
	modify(cur<<1,x,y,v),modify(cur<<1|1,x,y,v);
	pushup(cur);
	return ;
}
int n,m;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin >> n >> m;
    for(int i = 1;i <= n;i ++) cin >> a[i];
    build(1,1,n);
    while(m --){
    	int op,x,y,k;
    	cin >> op >> x >> y;
    	if(op == 1){
    		cin >> k;
    		modify(1,x,y,k);
		}
		else if(op == 2) cout << fixed << setprecision(4) << q_aver(1,x,y) << '\n';
		else cout << fixed << setprecision(4) << q_fc(x,y) << '\n';
	}
    return 0;
}
2023/2/28 16:22
加载中...