Cloud clipboard

AC Code

使用线段树维护方差的 AC 代码

文件
P1471.cpp
语言
cpp
规模
140 行 · 3.3 KB
更新
2026年9月17日
下载源码
#include<bits/stdc++.h>
#include<bits/extc++.h>
#ifndef ONLINE_JUDGE
// #define OPEN_FILE
// #define OPEN_TIME
#endif
#define AC return 0;
#define lowbit(x) (x&(-x))
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
using namespace std;
const int maxn=1e6+10,INF=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-8,Pi=acos(-1);
mt19937_64 mt(1145);
int n,m;
double a[maxn];
struct Tag{
    double add;
    bool operator==(const Tag &x)const{return add==x.add;}
    Tag operator+(const Tag &x)const{return {add+x.add};}
};
struct Info{
    double sum,sum2,len;
    Info operator+(const Info &x)const{
        return {sum+x.sum,sum2+x.sum2,len+x.len};
    }
    Info operator+(const Tag &x)const{
        return {sum+x.add*len,sum2+2*x.add*sum+x.add*x.add*len,len};
    }
};

struct SegTree{
    struct Node{
        Info sum;
        Tag tag;
    }t[maxn<<2];
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define sum(p) t[p].sum
#define tag(p) t[p].tag
    void AddTag(int p,Tag k){
        tag(p)=tag(p)+k;
        sum(p)=sum(p)+k;
    }
    void PushDown(int p){
        if(tag(p)==Tag()) return;
        AddTag(ls(p),tag(p));
        AddTag(rs(p),tag(p));
        tag(p)={};
    }
    void PushUp(int p){
        sum(p)=sum(ls(p))+sum(rs(p));
    }
    void Add(int p,int l,int r,int L,int R,Tag k){
        if(L<=l&&R>=r) return AddTag(p,k);
        if(l>R||r<L) return;
        PushDown(p);
        int mid=l+r>>1;
        Add(ls(p),l,mid,L,R,k);
        Add(rs(p),mid+1,r,L,R,k);
        PushUp(p);
    }
    void Change(int p,int l,int r,int x,Info k){
        if(l==r) return sum(p)=k,void();
        PushDown(p);
        int mid=l+r>>1;
        if(x<=mid) Change(ls(p),l,mid,x,k);
        else Change(rs(p),mid+1,r,x,k);
        PushUp(p);
    }
    Info Query(int p,int l,int r,int L,int R){
        if(L<=l&&R>=r) return sum(p);
        if(l>R||r<L) return {};
        PushDown(p);
        int mid=l+r>>1;
        return Query(ls(p),l,mid,L,R)+Query(rs(p),mid+1,r,L,R);
    }
    void Add(int l,int r,Tag k){
        Add(1,1,n,l,r,k);
    }
    Info Query(int l,int r){
        return Query(1,1,n,l,r);
    }
    void Build(int p,int l,int r){
        sum(p)={},tag(p)={};
        if(l==r) return sum(p)={a[l],a[l]*a[l],1},void();
        int mid=l+r>>1;
        Build(ls(p),l,mid);
        Build(rs(p),mid+1,r);
        PushUp(p);
    }
}t;

void solve() {
    int opt,l,r;
    double k;
    while(m--) {
        cin>>opt>>l>>r;
        if(opt==1) {
            cin>>k;
            t.Add(l,r,{k});
        }else if(opt==2) {
            auto[sum,sum2,len]=t.Query(l,r);
            printf("%.4lf\n",sum/len);
        }else {
            auto[sum,sum2,len]=t.Query(l,r);
            double bar=sum/len;
            double res=sum2-2*bar*sum;
            printf("%.4lf\n",(res/len)+bar*bar);
        }
    }
}
void init() {
    cin>>n>>m;
    for(int i=1;i<=n;++i) 
        cin>>a[i];
    t.Build(1,1,n);
}
int main() {
#ifdef OPEN_FILE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
#endif
#ifdef OPEN_TIME
    auto StartTime=clock();
#endif
    // ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    int T=1;
    // cin>>T;
    // while(cin>>n) {
    while(T--) {
        init();
        solve();
    }
#ifdef OPEN_TIME
    cerr<<"used: "<<(double)(clock()-StartTime)/CLOCKS_PER_SEC*1000<<" ms"<<endl;
#endif
    AC
}